Wake-on-LAN
Tuesday, May 29, 2012
Wake-on-LAN is an ethernet standard that allows a computer to be turned on or woken up by a network message. This is a kinda-fun-sometimes-useful feature that I thought we should have in Factor.
The way the protocol works is to broadcast a “magic packet” that contains information describing the computer you want to wakeup. From the Wikipedia article:
The magic packet is a broadcast frame containing anywhere within its payload 6 bytes of all 255 (FF FF FF FF FF FF in hexadecimal), followed by sixteen repetitions of the target computer’s 48-bit MAC address, for a total of 102 bytes. Since the magic packet is only scanned for the string above, and not actually parsed by a full protocol stack, it may be sent as any network- and transport-layer protocol, although it is typically sent as a UDP datagram to port 7 or 9, or directly over Ethernet as EtherType 0x0842.
First, we need a way to turn a MAC address into an array of bytes:
: mac-address-bytes ( mac-address -- byte-array )
":-" split [ hex> ] B{ } map-as ;
Next, we need a way to construct the “magic packet” according to the specification:
: wake-on-lan-packet ( mac-address -- bytearray )
[ 16 ] [ mac-address-bytes ] bi* <array> concat
B{ 0xff 0xff 0xff 0xff 0xff 0xff } prepend ;
Now that we have the “magic packet”, we can create a datagram port configured to send broadcast packets (using a recent commit that made this easy and cross-platform):
: wake-on-lan ( mac-address broadcast-ip -- )
[ wake-on-lan-packet ] [ 9 <inet4> ] bi*
f 0 <inet4> <broadcast> [ send ] with-disposal ;
It’s easy enough to test this using Mac OS since most modern Mac hardware supports Wake-on-LAN. You can configure it via the System Preferences Energy Saver panel, in the Options tab. Marking the “Wake for network access” checkbox enables Wake-on-LAN support. For other platforms, read more about receiving the magic packet.
The code for this is on my GitHub.