Simple Wake-on-LAN Wrapper Script

Our home network includes a number of Linux-based systems and one Apple iMac. Because the Mac hosts all of our family photos, and because printing from a Mac to a Linux printer is a headache, it made the most sense for us to connect the printer directly to the Mac. However, this creates an issue when printing from one of the other computers: if the Mac is asleep, the shared printer does not respond to requests.

The workaround is simple: get up, walk over to the Mac, and hit the space bar or click the mouse to wake up the machine before trying to print. But we don’t want to get up, so we’ll issue a Wake-on-LAN packet to the Mac instead, using wakeonlan.

wakeonlan is a simple Perl script written by Jose Pedro Oliveira and maintained by Ico Doornekamp. It is available from the repositories for most Linux distributions. The script broadcasts “magic packets” over the network that are read by WOL-compatible interfaces. If the interface recognizes its own MAC address in the magic packet, the interface signals the host machine to “wake up.”

Sure, it’s a neat trick, but we have to know the destination machine’s MAC address. So we can either make MAC address flash cards for our LAN, or we can write a wrapper script to find the MAC address for us and issue the packet.

Finding the MAC Address

To find the MAC address we can use arp, a standard Linux utility, to read the local host’s ARP cache. The ARP cache is an important part of any Ethernet network–it stores a table of every known host on the network by IP and MAC address. Essentially, it serves as the local host’s “address book,” making sure requests to a given IP address are sent to the appropriate network interface. Most of the time, this translation is done in the background while the user remains happily oblivious. But Wake-on-LAN packets are special, and they need our help to get to where they’re going.

The output of arp looks something like this:

$ arp
Address         HWtype  HWaddress          Flags Mask     Iface
server          ether   ab:cd:ef:01:23:45  C              eth0
bobs-machine    ether   11:22:33:44:55:66  C              eth0
arpeggio        ether   56:45:34:23:12:01  C              eth0
My-iMac.domain  ether   c8:2a:14:ff:ff:ff  C              eth0
My-iMac.local   ether   e4:ce:8f:00:00:00  C              eth0

We’re interested in the third column–the MAC address–of the machine called My-iMac. Because the iMac’s Ethernet and Wi-Fi interfaces are both enabled, the same hostname shows up twice (albeit with different domains). We’re only interested in the Ethernet interface, which, fortunately, shows up first (the output of arp does not tell us which is which–in my case, I know this because I’ve set up static DHCP leases on my home network–finding this out may require some digging or trial and error). This means that we can write our script to search for the first line matching the hostname, then to extract the third column from that line. We accomplish this using grep and awk, respectively.

$ arp | grep -i -m1 imac
My-iMac.domain  ether   c8:2a:14:ff:ff:ff  C              eth0
$ arp | grep -i -m1 imac | awk '{print $3}'
c8:2a:14:ff:ff:ff

For this discussion we’ll bypass a detailed explanation of the grep and awk commands. See the Linux man pages for details.

Now that we have a command line string that finds the right MAC address, we can write our script.

The Script

Below is our Wake-on-LAN wrapper script, saved in a file named wol:

#!/bin/sh

MACADDR=`arp | grep -i -m1 $1 | awk '{print $3}'`
wakeonlan $MACADDR

All we’ve done is taken our command line string and replaced the hostname search string (imac) with the variable $1, which is interpreted by the shell as the first argument passed to the script by the user. This way we can use the same script to send WOL packets to any machine on the network. Executing the script looks like this:

$ ./wol imac

There. Wasn’t that easier than getting up and hitting the space bar?

Further Reading

1 Comment

  • Awesome article! We have a totally out of bounds problem with corporate attempting to manage support and test lab resources resulting in these nodes becoming remotely unavailable for jobs or automation tasks.

    -Brian

1 Trackback

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>