Posted: Tue Mar 21, 2017 2:35 Post subject: WOL configuration
Hello Guys,
Need your help with something.
My box is already configured to WOL. I can use the router interface to wake it.
Now, I need to wake it automatically when there is a request on port 32400 local or remote.
I am using this script:
Code:
#!/bin/sh
#Enable JFFS2 and place script in /jffs/ then run on startup in web interface.
#You can check the log from http://192.168.1.1/user/wol.html
echo "<meta http-equiv=\"refresh\" content=\"10\">" > $LOGFILE
echo "AUTO WOL Script started at" `date` "<br>" >> $LOGFILE
while sleep $INTERVAL;do
NEW=`dmesg | awk '/ACCEPT/ && /DST='"$TARGET"'/ && /DPT='"$PORT"'/ {print }' | tail -1`
SRC=`dmesg | awk -F'[=| ]' '/ACCEPT/ && /DST='"$TARGET"'/ && /DPT='"$PORT"'/ {print $7}' | tail -1`
LINE=`dmesg | awk '/ACCEPT/ && /DST='"$TARGET"'/ && /DPT='"$PORT"'/'`
if [ "$NEW" != "" -a "$NEW" != "$OLD" ]; then
if ping -qc $NUMP $TARGET >/dev/null; then
echo "NOWAKE $TARGET was accessed by $SRC and is already alive at" `date` "<br>">> $LOGFILE
else
echo "WAKE $SRC causes wake on lan at" `date` "<br>">> $LOGFILE
$WOL -i $BROADCAST -p $WOLPORT $MAC >> $LOGFILE
echo "<br>" >> $LOGFILE
sleep 5
fi
OLD=$NEW
fi
echo "<br> Pass" >> $LOGFILE
done
Apart from the MAC, all other fields are my current configs.
I am enabling Syslogd, Log Management (ACCEPTED=Enable) and this service is using UPNP. This service is called Plex. Media streamer. The ideia is to wake my machine when I want to watch something remotelly. And sleep when idle.
I am putting this code at Admin->Command->Run Command. The plan is to put it as a Startup command.
I am on Linksys EA6900 - v3.0-r30965M kongac
I am login to the console and can't get any connection to that port using dmesg.
My tests are on same local network, but I can't find anything when using my phone network also.
What am I doing wrong here ?
Seems the router is not capturing the local traffic logs.
I am using dmesg for this.
Can any of you confirm if this is as expected ?
Linksys se6900 - Firmware: DD-WRT v3.0-r31575M kongac (03/21/17)
Just so I am clear on my question: I am using dmesg to capture traffic information on the router.
Using that, I am unable to capture LAN traffic. I am able to capture WAN traffic. All that using port 32400.
I am using upnp and port forwarding port 32400 to my fixed IP server 192.168.1.2 as shown on the script variables.
Just so I am clear on my question: I am using dmesg to capture traffic information on the router.
Using that, I am unable to capture LAN traffic. I am able to capture WAN traffic. All that using port 32400.
I am using upnp and port forwarding port 32400 to my fixed IP server 192.168.1.2 as shown on the script variables.
Hey Kong,
many many thanks for the reply.
Is there a way to accomplish what I am trying to capture ? I mean, how can I capture the LAN traffic handled by the switch?
Thanks again !
This is what I got from Kong:
Just access it from "WAN" means, connect to the WAN IP from your client or the WAN hostname, e.g. dyndns name. Otherwise your would have to create vlans etc route between them.
The app does not allow me to input a service name, just IP, and I don't have a fixed IP, just dynamic.
I am not willing to create VLANs just to accomplish this.
I have modified the script to monitor the port 32400, as the app also connects to the cloud. Apart from some tuning and comments.
Code:
#!/bin/sh
#Enable JFFS2 and place script in /jffs/ then run on startup in web interface.
#You can check the log from http://192.168.1.1/user/wol.html
echo "<meta http-equiv=\"refresh\" content=\"10\">" > $LOGFILE
echo "["`date`"] AUTO WOL Script started. <br>" >> $LOGFILE
echo "For server: $TARGET:$PORT <br>" >> $LOGFILE
echo "WOL for MAC: $MAC on port $WOLPORT <br> <br>" >> $LOGFILE
while sleep $INTERVAL; do
# dmesg only captures IPTABLE rules and connections (WAN) it does not capture LAN connections. LAN is handled by the switch.
NEW=`dmesg | awk '/ACCEPT/ && /DPT='"$PORT"'/ {print }' | tail -1`
if [ ! -z "$NEW" -a "$NEW" != "$OLD" ]; then
SRC=`echo $NEW | awk -F'[=| ]' '{print $7}'`
# uncomment if you want to troubleshoot
#echo $NEW "<br>">> $LOGFILE
if ping -qw $PINGTIME $TARGET >/dev/null; then
echo "NOWAKE $TARGET was accessed by $SRC and is already alive at" `date` "<br>">> $LOGFILE
else
echo "WAKE $SRC causes wake on lan at" `date` "<br>">> $LOGFILE
$WOL -i $BROADCAST -p $WOLPORT $MAC >> $LOGFILE
echo "<br>" >> $LOGFILE
sleep 1
fi
OLD=$NEW
fi
done
I wanted some community assistance on this one.
I believe we can manage to create a real effective WOL script for multiple purposes here ....
As I already posted, dmesg is only capturing WAN traffic.
I just managed to capture the LAN traffic from the switch using tcpdump.
But that really consumes CPU !
I believe my router can handle it, but I want this to work for everybody.
Can anybody think on another way of capturing the switch traffic ?
#echo "<meta http-equiv=\"refresh\" content=\"10\">" > $LOGFILE
#echo "["`date`"] AUTO WOL Script started. <br>" >> $LOGFILE
#echo "For server: $TARGET:$PORT <br>" >> $LOGFILE
#echo "WOL for MAC: $MAC on port $WOLPORT <br> <br>" >> $LOGFILE
tcpdump -q -n -i vlan1 -P out 'dst host '$TARGET' && port '$PORT 2>/dev/null | while read NEW ; do
# Get the line in seconds, to minimize the number of processed commands.
NEW_TIME=`echo $NEW | awk -F'.' '{print $1}'`
if [ "$NEW_TIME" != "$OLD_TIME" ]; then
# Get the source IP for logging
#SRC=`echo $NEW | awk -F'[.| ]' '{print $4"."$5"."$6"."$7}'`
if ping -qw $PINGTIME $TARGET >/dev/null; then
#echo "[`date`] NOWAKE - $TARGET accessed by $SRC <br>">> $LOGFILE
touch /dev/null
else
#echo "[`date`] _WAKE_ - $TARGET accessed by $SRC <br>">> $LOGFILE
$WOL -i $BROADCAST -p $WOLPORT $MAC >> $LOGFILE
#echo "<br>" >> $LOGFILE
sleep $INTERVAL
fi
OLD_TIME=$NEW_TIME
fi
done
Note that the tcpdump command is the key command.
I am not very familiar with it, and I came up with this from examples on the internet and man.
The following is capturing all the connections, and I am afraid that this will consume a lot of CPU and memory:
Code:
tcpdump -q -p -n -i vlan1 -P out 'dst host '$TARGET' && port '$PORT 2>/dev/null
I came up with this, but I am not very happy with it.
Code:
tcpdump -q -p -n -i vlan1 -P out 'tcp[tcpflags] & (tcp-syn) != 0 and dst host '$TARGET' && port '$PORT 2>/dev/null
With this, I am getting all the initial connection attempts. This is not ideal, cause it is not capturing traffic when you already have the app opened (in background) on your device or browser.
I am checking about package sizes now ... but doesn't seem to be a good filter for my case ....
I could use:
Code:
if [ "$NEW_TIME" > "$OLD_TIME" ]; then
...
OLD_TIME=$NEW_TIME+10 #(seconds)
But this is not the way I like doing things .... and would still consume more CPU/Memory then needed.
I will share 2 scripts: one with the log process commented and another with it.
You just need to adjust the variables on the beginning of the file. All those are my real values, with the exception of the MAC.
With Log:
Code:
#!/bin/sh
#Enable JFFS2 and place script in /jffs/ then run on startup in web interface.
#You can check the log from http://192.168.1.1/user/wol.html
INTERVAL=2
PINGTIME=1
OLD_TIME=""
PORT=32400
WOLPORT=9
TARGET=192.168.1.2
BROADCAST=192.168.1.255
MAC=00:00:00:00:00:00
WOL=/usr/sbin/wol
LOGFILE="/tmp/www/wol.html"
# Never change LOGLINESTOSTORE to under 100. It will create pretty much a loop on the cleanup log procedure
LOGLINESTOSTORE=10
PURGECOUNT=0
echo "<meta http-equiv=\"refresh\" content=\"10\">" > $LOGFILE
echo "["`date`"] AUTO WOL Script started. <br>" >> $LOGFILE
echo "For server: $TARGET:$PORT <br>" >> $LOGFILE
echo "WOL for MAC: $MAC on port $WOLPORT <br> <br>" >> $LOGFILE
tcpdump -q -n -i any -p -P out -K -l -O -U 'dst host '$TARGET' and dst port '$PORT'' 2>/dev/null | while read NEW ; do
# Get the line in seconds, to minimize the number of processed commands.
NEW_TIME=`echo $NEW | awk -F'.' '{print $1}'`
if [ "$NEW_TIME" != "$OLD_TIME" ]; then
# Get the source IP for logging
SRC=`echo $NEW | awk -F'[.| ]' '{print $4"."$5"."$6"."$7}'`
# If box is alive (responding to ping)
if ping -qw $PINGTIME $TARGET >/dev/null; then
echo "[`date`] NOWAKE - $TARGET accessed by $SRC <br>">> $LOGFILE
#touch /dev/null
else
echo "[`date`] _WAKE_ - $TARGET accessed by $SRC <br>">> $LOGFILE
$WOL -i $BROADCAST -p $WOLPORT $MAC >> $LOGFILE
fi
OLD_TIME=$NEW_TIME
# Cleanup log file procedure, keeping the header and the last 10 last WAKE log lines
if [ "`wc -l $LOGFILE | awk -F'[ ]' '{print $1}'`" -gt "$LOGLINESTOSTORE" ]; then
head -n 4 $LOGFILE > /tmp/www/wol.tmp
PURGECOUNT=$((PURGECOUNT+1))
echo "Log File purged $PURGECOUNT times, last one at $NEW_TIME <br> " >> /tmp/www/wol.tmp
grep _WAKE_ $LOGFILE | tail -n 10 >> /tmp/www/wol.tmp
mv /tmp/www/wol.tmp $LOGFILE
echo "<br>" >> $LOGFILE
fi
sleep $INTERVAL
fi
done
Without Log:
Code:
#!/bin/sh
#Enable JFFS2 and place script in /jffs/ then run on startup in web interface.
#You can check the log from http://192.168.1.1/user/wol.html
INTERVAL=2
PINGTIME=1
OLD_TIME=""
PORT=32400
WOLPORT=9
TARGET=192.168.1.2
BROADCAST=192.168.1.255
MAC=00:00:00:00:00:00
#WOL=/usr/sbin/wol
#LOGFILE="/tmp/www/wol.html"
# Never change LOGLINESTOSTORE to under 100. It will create pretty much a loop on the cleanup log procedure
#LOGLINESTOSTORE=10
#PURGECOUNT=0
#echo "<meta http-equiv=\"refresh\" content=\"10\">" > $LOGFILE
#echo "["`date`"] AUTO WOL Script started. <br>" >> $LOGFILE
#echo "For server: $TARGET:$PORT <br>" >> $LOGFILE
#echo "WOL for MAC: $MAC on port $WOLPORT <br> <br>" >> $LOGFILE
tcpdump -q -n -i any -p -P out -K -l -O -U 'dst host '$TARGET' and dst port '$PORT'' 2>/dev/null | while read NEW ; do
# Get the line in seconds, to minimize the number of processed commands.
NEW_TIME=`echo $NEW | awk -F'.' '{print $1}'`
if [ "$NEW_TIME" != "$OLD_TIME" ]; then
# Get the source IP for logging
#SRC=`echo $NEW | awk -F'[.| ]' '{print $4"."$5"."$6"."$7}'`
# If box is alive (responding to ping)
if ping -qw $PINGTIME $TARGET >/dev/null; then
#echo "[`date`] NOWAKE - $TARGET accessed by $SRC <br>">> $LOGFILE
touch /dev/null
else
#echo "[`date`] _WAKE_ - $TARGET accessed by $SRC <br>">> $LOGFILE
$WOL -i $BROADCAST -p $WOLPORT $MAC #>> $LOGFILE
fi
OLD_TIME=$NEW_TIME
# Cleanup log file procedure, keeping the header and the last 10 last WAKE log lines
#if [ "`wc -l $LOGFILE | awk -F'[ ]' '{print $1}'`" -gt "$LOGLINESTOSTORE" ]; then
# head -n 4 $LOGFILE > /tmp/www/wol.tmp
# PURGECOUNT=$((PURGECOUNT+1))
# echo "Log File purged $PURGECOUNT times, last one at $NEW_TIME <br> " >> /tmp/www/wol.tmp
# grep _WAKE_ $LOGFILE | tail -n 10 >> /tmp/www/wol.tmp
# mv /tmp/www/wol.tmp $LOGFILE
# echo "<br>" >> $LOGFILE
#fi
sleep $INTERVAL
fi
done
I have been working hard to get this script to work. I admit that I am running Plex on a Mac but the findings I have done might also be useful for non-Mac-users. I had several issues to fix before the script worked great, but now it is al running smoothly
First of all I’d like to say that setting up the router correctly is very important to prevent issues later while using the WOL script. I’ve had help setting up my DD-WRT router as a second router because I am bound to mu ISP router. Unfortunately the help I got was on a Dutch forum so not everybody will be able to follow this, for those who do: page 36/37 on the following site:
After setting up the router WOL worked, and using the script from jaoptc, it also worked when opening PLEX apps. The first two problems followed. 1) after a few minutes of sleep, the Plex apps didn’t trigger WOL anymore. Manual WOL still worked. 2) Opening the PLEX app on my LG WebOS 3 tv didn’t trigger WOL at all.
The problem seemed to be that the Mac address disappeared from the router ARP table. Long story short: the solution to this problem was to add another line to the script under Purgecount (see script at the bottom of the post).
While testing this solution another problem came up (don’t worry if this happens to you also, the green line works). The following problem was that the Mac woke up after a minute of sleep. It would then fall asleep after another minute and so forth.
While this seemed to be one problem, the sleep and wake where separate problems. Due to the fact that both of these problems need you to disable SIP (System Integrity Protection) I will explain the solutions of both here. The reason you need to disable SIP is to enable you to edit system files you normally can’t edit.
The first solution is for the sudden wakes of the Mac. I looked deeper in to the reason why the Mac waked by entering the following command in Terminal:
Step 1 is to disable SIP:
To disable SIP you start up the Mac in Recovery Mode. This is achieved by shutting down the Mac. When powering the Mac back on hold the CMD + R buttons until the Apple logo appears. From there go to Utilities > Terminal and enter the following
csrutil enable
Hit enter and when you see the confirmation restart the Mac and let the Mac boot normally.
After SIP is disabled and the Mac has restarted open Terminal and enter the following command:
Go to the line <string>/usr/sbin/mDNSResponder</string> and insert the following line:
<string>-NoMulticastAdvertisements</string>
After a reboot the wake reason RTC (Alarm) should be fixed.
The second problem which requires SIP to be disabled is the problem that the Mac fell asleep after a short wake period (< 1 minute). The core problem appeared to be that the Mac didn’t fully wake, but did a Dark Wake. The Mac checked if there was a valid reason for the WOL. If not, the Mac returned to the sleeping state. The solution is:
1 Open a Terminal window.
2 Type the following: cd /Library/Preferences/SystemConfiguration
and hit enter
3 Edit com.apple.Boot.plist by typing: sudo nano com.apple.Boot.plist
4 Move the insertion point down to the <string> associated with the Kernel Flags <key>
5 Type darkwake=0
6 Hit CTR + X, enter Y and hit Enter to save and quit the file.
7 Reboot the system.
After a reboot you need to enable SIP again.
This is done the same as disabling it, but by typing
csrutil enable
After these modifications my Mac sleeps and wakes perfectly.
In the process I found a lot of information about Sleep modes on the Mac and on Hibernation.
WOL also works when Hibernation is enabled. Since this is not a standard setting there is another command needed.
Beneath you can find my final DD-WRT script. The TARGET, BROADCAST and MAC sections need to be edited according to your setup.
Hope this helps some of you!!
Regards
Patrick
———————————————————————————————————————————
#!/bin/sh
#Enable JFFS2 and place script in /jffs/ then run on startup in web interface.
#You can check the log from http://192.168.1.1/user/wol.html
INTERVAL=2
PINGTIME=1
OLD_TIME=""
PORT=32400
WOLPORT=9
TARGET=192.168.1.252
BROADCAST=192.168.1.255
MAC=XX:XX:XX:XX:XX
WOL=/usr/sbin/wol
LOGFILE="/tmp/www/wol.html"
# Never change LOGLINESTOSTORE to under 100. It will create pretty much a loop on the cleanup log procedure
LOGLINESTOSTORE=500
PURGECOUNT=0
# To Broad cast the WOL when Server is out of the ARP table.
arp -i br0 -s $TARGET $MAC
echo "<meta http-equiv=\"refresh\" content=\"10\">" > $LOGFILE
echo "["`date`"] AUTO WOL Script started. <br>" >> $LOGFILE
echo "For server: $TARGET:$PORT and MAC: $MAC on port $WOLPORT <br>" >> $LOGFILE
tcpdump -q -n -i any -p -P out -K -l -O -U 'dst host '$TARGET' and dst port '$PORT'' 2>/dev/null | while read NEW ; do
# Get the line in seconds, to minimize the number of processed commands.
NEW_TIME=`echo $NEW | awk -F'.' '{print $1}'`
if [ "$NEW_TIME" != "$OLD_TIME" ]; then
# Get the source IP for logging
SRC=`echo $NEW | awk -F'[.| ]' '{print $4"."$5"."$6"."$7}'`
# If box is alive (responding to ping)
if ping -qw $PINGTIME $TARGET >/dev/null; then
echo "[`date`] NOWAKE - $TARGET accessed by $SRC <br>">> $LOGFILE
#touch /dev/null
else
echo "[`date`] _WAKE_ - $TARGET accessed by $SRC <br>">> $LOGFILE
$WOL -i $BROADCAST -p $WOLPORT $MAC >> $LOGFILE
echo "<br>" >> $LOGFILE
fi
OLD_TIME=$NEW_TIME
# Cleanup log file procedure, keeping the header and the last 10 last WAKE log lines
if [ "`wc -l $LOGFILE | awk -F'[ ]' '{print $1}'`" -gt "$LOGLINESTOSTORE" ]; then
head -n 3 $LOGFILE > /tmp/www/wol.tmp
PURGECOUNT=$((PURGECOUNT+1))
echo "Log File purged $PURGECOUNT times, last one at $NEW_TIME <br> " >> /tmp/www/wol.tmp
grep _WAKE_ $LOGFILE | tail -n 10 >> /tmp/www/wol.tmp
mv /tmp/www/wol.tmp $LOGFILE
echo "<br>" >> $LOGFILE
fi
sleep $INTERVAL
fi
done