home January 01, 2017

Wake On LAN (WOL)


Wake On LAN (WOL) is the ability of a network interface to turn the system on or awaken it from hibernation when a "magic packet" is received over the network from a remote system. This is especially useful to turn a system on remotely and then power it off remotely to save power or reduce the heat or noise generated in the room.

The Magic Packet is a broadcast frame containing anywhere within its payload 6 bytes of ones FF FF FF FF FF FF followed by sixteen repetitions of the target computer's MAC address. 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 a broadcast packet of any network- and transport-layer protocol. It is typically sent as a UDP datagram to port 0, 7 or 9, or, in former times, as an IPX packet.

Security Note: Magic packets are sent via the data link or OSI-2 layer, which is not secure and can be used or abused by anyone on the same LAN. Firewalls can be used to prevent clients outside the LAN from sending packets in.

Lets setup a Linux box on an internal LAN that can be WOL (Wake On LAN) from an OpenBSD box on the same internal network. We currently use this exact same setup to turn on our MythTV Linux box from an OpenBSD workstation everyday at 3:50pm. Then at 3:10am the MythTV box will power itself off to save power and lower our power and cooling bills.

Getting Started - Checking Supported Hardware

Most modern motherboards with an embedded Ethernet controller support WOL without the need for an external cable. Older motherboards must have a WAKEUP-LINK header onboard and connected to the network card via a special 3-pin cable; however, systems supporting the PCI 2.2 standard coupled with a PCI 2.2 compliant network adapter typically do not require a WOL cable as the required standby power is relayed through the PCI bus. Finally, you must have an ATX v2.0 or above compliant power supply. Most systems made after 2004 have all of these hardware requirements.

Make sure the BIOS is WOL enabled

The first task is to make sure that the machine you want to wake up is WOL capable and WOL enabled. In our example this would be the MythTV Linux box. You will need to go into the BIOS and go to the Power Management area. Most of the time you can access the BIOS by repeatedly hitting the "delete" key during boot. You are looking to enable an option like "WOL", "WOL (PME)", or "Power by PCI device". Since every BIOS manufacture is slightly different we can not tell you exactly what to change.

Setting the target machine's NIC to WOL mode

When you tell a Linux box to power off or halt, the network driver for the NIC decides what state to put the network card into. Normally the driver will turn the card off for security. You probably do not want some stranger randomly turning on your systems remotely. When the machine is soft-off the network light may be lit on the card and a switch it is connected to sees the NIC as connected, but the card is essentially off because it is not listening for any packets. We need to make the NIC go into WOL mode when the Linux box is powered off so it will be looking for our "magic packet".

We can force the NIC into WOL mode independent of the NIC driver on any Linux box by making a simple init.d script we will call "wakeonlan". The wakeonlan script will set the primary network card eth0 into WOL mode "umbg" when the box is turned soft-off. Make a new file "/etc/init.d/wakeonlan" and put the following into it:

## moneyslow.com -- Wake On LAN for Linux
## /etc/init.d/wakeonlan
#
# chkconfig: 2345 99 99
# description: Force NIC into WOL mode
#
ethtool -s eth0 wol umbg
exit

The WOL options for the network card are as follows:

Finally, you need to make sure that when the Linux system boots it will run the "wakeonlan" script to initialize the NIC. Do the following:

  1. chmod 755 /etc/init.d/wakeonlan - Make wakeonlan executable by everyone
  2. chkconfig --add wakeonlan - Redhat or CentOS Only: Add symlinks in the rc2.d through rc5.d to the /etc/init.d script
  3. update-rc.d wakeonlan defaults - Debian or Umbuntu ONLY: Add symlinks in the rc2.d through rc5.d to the /etc/init.d script

Now the Linux box is ready. When Linux boots it will put the NIC into WOL mode. When you type "poweroff" or hit the power button on the machine it will go into soft-off mode. Then when the NIC sees the "magic packet" sent from the OpenBSD box over the network the machine will boot like normal.

Allow the OpenBSD box to WOL the Linux box over the network

In order to send a "magic packet" to the target Linux machine to WOL we need to know three items of information: the ip address, the MAC address and the hostname of the Linux box. We can get the ip and MAC if you execute an "ifconfig" on the linux box. For example, our linux box says the following:

[root@linux ~]# ifconfig 
eth0      Link encap:Ethernet  HWaddr 00:1e:38:26:22:28
          inet addr:10.10.10.3  Bcast:10.10.10..255  Mask:255.255.255.0
          inet6 addr: 4e40::404:444f:fe44:44ac/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:29767315 errors:0 dropped:0 overruns:0 frame:0
          TX packets:18008531 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:4193669561 (3.9 GiB)  TX bytes:2041714893 (1.9 GiB)
          Base address:0xef00 Memory:eeee0000-g7ee0000 

The ip address is "10.10.10.3" and the MAC address is "00:1e:38:26:22:28". Finally, we need to know the hostname of the Linux box as seen by the OpenBSD box over the network. Type host and the ip address like, "host 10.10.10.3". The result for our MythTV Linux box is "mythtv.domain.home".

Now that we have the ip, the MAC and the hostname we can use the utility "wol" installed from packages on our OpenBSD box (pkg_add wol). This will generate the "magic packet" using the supplied MAC and unicast it to the ip address we specify. BTW, there are many utilities for everything from windows to mac to linux that can generate the "magic packet" for you.

This is our WOL script with a little fail-over built in. It will do the following:

  1. Ping the linux box. If it is up break the while loop and exit. If the box is not up...
  2. Delete the arp entry for the hostname "mythtv.domain.home" from the OpenBSD box. This is needed since the OpenBSD may see the arp entry for the MythTV Linux box and "incomplete".
  3. Add the arp entry for "mythtv.domain.home" with MAC "00:1e:38:26:22:28". This will make sure the OpenBSD box knows where to send the WOL magic packet.
  4. sleep 3 seconds
  5. Send the WOL "magic packet" to the Linux box at ip address "10.10.10.3" and MAC "00:1e:38:26:22:28".
  6. sleep 90 seconds. This should be long enough for the Linux box to boot.
  7. Ping the linux box. If it is up break the while loop and exit. If the Linux box is not up then begin the while loop again. The while loop will run a total of four(4) times and then the script will end. If the Linux box is not up yet there may be another reason it is still down and the script should be stopped.

## Wake On LAN @ moneyslow.com
## /tools/wol_poweron.sh

IP="10.10.10.3"
MAC="00:1e:38:26:22:28"
HOSTNAME="mythtv.domain.home"

count="0"
while [ $count -lt 3 ]
 do
  ping -nqc 3 -w 5 $IP > /dev/null && break
  /usr/sbin/arp -d $HOSTNAME
  /usr/sbin/arp -s $HOSTNAME $MAC
  sleep 3
  /usr/local/bin/wol -i $IP $MAC
  sleep 90
  ping -nqc 3 -w 5 $IP > /dev/null && break
  count=$[$count+1]
done

NUT (Network UPS Tools) will monitor your UPS (uninteruptable power supply) and can send you mail or log power events. For more information about OpenBSD's install of NUT check out our NUT UPS monitor on OpenBSD "how to".

Time for testing

Lets to see if all the hard work paid off. Start with both of the machines booted and on. Make sure you can ping the linux box from the OpenBSD box. This way we can make sure the packets get to the machine. Now, log into the linux box and type "poweroff" or type "halt" and hit the power button on the front of the Linux box. This will shut down the linux box and go into a soft-off mode. This means that the linux box is essentially off except the NIC is still powered and listening for our "magic packet"

Manually execute the "wol_poweron.sh" script on the OpenBSD as root or use sudo. We need elevated access in order to manipulate the ARP table. The OpenBSD machine will send the "magic packet" to the linux box. If the BIOS is WOL enabled and the NIC is listening for WOL packets then the linux box should now be booting. Congratulations, you are all done!

Helpful Hints

We use WOL to power up our MythTV box. These are just notes that you can setup two cron jobs, one to shut down the linux box nightly at 3:10am and on on the OpenBSD box to WOL power up the linux box at 4:50pm.

OpenBSD script. Power up linux box over network using WOL

#minute (0-59)
#|    hour (0-23)
#|    |    day of the month (1-31)
#|    |    |   month of the year (1-12 or Jan-Dec)
#|    |    |   |   day of the week (0-6 with 0=Sun or Sun-Sat)
#|    |    |   |   |   commands
#|    |    |   |   |   |
## Wake On LAN power on 
50   15    *   *   *   logger "Powering Up WOL System";/tools/wol_poweron.sh

Linux script. PowerOff linux box to save power at night

#minute (0-59)
#|    hour (0-23)
#|    |    day of the month (1-31)
#|    |    |   month of the year (1-12 or Jan-Dec)
#|    |    |   |   day of the week (0-6 with 0=Sun or Sun-Sat)
#|    |    |   |   |   commands
#|    |    |   |   |   |
## PowerOff WOL machine to save power
10   3    *   *   *    logger "Powering Down System";/usr/bin/poweroff