Waking a sleeping machine from a remote location

To Telnet, SSH, Share, or VNC to a Mac at a remote location as it now stands, the target machine must be awake, and its router (linking the internet to the machine) must be properly port forwarded to the target for that protocol. If the machine is asleep, you won’t get in because its ethernet or WiFi connection won’t be “listening”.

The EnergySaver Preference Pane’ s help says this about waking a sleeping machine: (where I assume that selecting one of these means that the machine’s internet or modem connection doesn’t sleep when the rest of the machine does).

But note that SSH, for example, will not wake the machine it targets because to do so requires a Wake On LAN packet. A WoL packet is fairly straight-forward (though not for me - I don’t know how to send a packet): it must include anywhere within it hexadecimal FF six times in a row, followed by the target’s MAC address 16 times (not sure about spacing between characters). The easiest way to do that is to send a broadcast from the target LAN’s router, since only the target machine (with the correct MAC address) will respond anyway. I haven’t tried this (because I don’t know how to do it), but I understand that Macs can be wakened this way.

Does anyone know how to do this from a script, i.e., send a WoL packet to a particular port on an AirPort Extreme that is set up to forward the packet to a sleeping Mac inside the LAN?

I’d appreciate some unequivocal “NOs” from readers who read this but don’t have a clue how to do it rather than no answer at all.

Here is your first ‘nope’ mate, sorry.

To send Wake-On-LAN packets, you need access to UDP sockets. I searched on Scripting Additions, but I did not find anything for UDP sockets (for TCP there is at least XNet). There is, however a WOL scripting addition by the same author as XNet. I have not installed it, but it looks like it always sends to the local broadcast address. Unfortunately, I think you will need a bit more flexibility for your project (specifically the sending WOL through a firewall+NAT device).

I use a Wake-On-LAN Perl script from time to time. I am sure WOL can be done in other languages. Any language environment that provide access to enough of the UDP API to send datagrams should work (socket, sendmsg/send/write, and maybe a few others like gethost* (or an equivalent), getproto*, etc.). So, if you do not like this Perl version, you can probably find others.

To install the Perl program, you can do the normal “/usr/bin/perl Makefile.PL && make install” process to install the script. However, since everything you need is really in one script and it needs no fancy installation, you can just copy the wakeonlan file from the unpacked wakeonlan-0.41.tar.gz file and use it directly (chmod 755 it and move it to some directory that is in your PATH (I have a ~/cmd directory for scripts like this)).

With wakeonlan (or an equivalent) in hand, you have the tool you need to start experimenting with the router configuration. First I would start with testing the WOL process locally to make sure it works correctly. I know a friend of mine has previously been able to get a DSL router to pass along WOL packets from the Internet to its internal network. So, it is possible in theory, but it was done with hardware other than an Airport Extreme.

The Perl program above uses UDP port 9 (“discard”) by default, and it seems as good a port as any most others (you would want to avoid a port on which many/any machines normally listen, since you would be allowing anyone from the Internet to hit those services with packets). The key will be to configure the router to forward incoming UDP port 9 packets to the internal network. You could have the router direct it to port 9 on the one machine you want to wake or, if you want to be able to wake multiple machines, you could try directing it to port 9 on the local broadcast address (usually something like 192.168.1.255).

If that works, you should be able to do “wakeonlan -i the-public-IP-of-your-router ethernet-address-of-target-machine; ssh public-IP-of-your-router:port-on-router-that-is-forwarded-to-SSH-on-the-target-machine”.

Thanks for the detailed rundown. I found a Mac OS X dmg file called Wake550, a bundle that includes what is probably the same Perl script as a resource. It seems to be set up to run on a LAN, but I haven’t played with it sufficiently to know whether it works through the AP Extreme. I’ll read it to see if I can figure out if it’s using UDP Port 9 so I can forward that.