Skip to content

dnaeon/cl-wol

Repository files navigation

cl-wol

cl-wol is a Common Lisp system and CLI application, which can power on remote systems using Wake on LAN (WoL).

Requirements

Installation

cl-wol is not yet in Quicklisp, so in order to install it you will need to clone the repo and add it to your Quicklisp local-projects.

cd ~/quicklisp/local-projects
git clone https://github.com/dnaeon/cl-wol.git

If you are installing the CLI application, you will also need a recent version of clingon, as the one found in Quicklisp is not yet updated to the latest release.

Systems

cl-wol provides the following systems.

The cl-wol.core system provides the core functionallity for powering on remote systems using Wake on LAN (WoL) by broadcasting a magic packet to a destination port and address.

The cl-wol.test system provides the test suite of cl-wol.core.

The cl-wol.cli system provides a command-line interface application, built on top of cl-wol.core, which comes with support for looking up hosts and their MAC addresses from a local SQLite database.

Usage

The following formats of MAC addresses are supported by cl-wol.

  • As a string in AA:BB:CC:DD:EE:FF format
  • As a string in AA-BB-CC-DD-EE-FF format
  • As a (simple-array (unsigned-byte 8) (6)) vector

API

The following section describes how to use the cl-wol.core system.

First, start your Lisp REPL and load the system.

CL-USER> (ql:quickload :cl-wol.core)
To load "cl-wol.core":
  Load 1 ASDF system:
    cl-wol.core
; Loading "cl-wol.core"

(:CL-WOL.CORE)

In order to wake a remote system identified by a given MAC address we first need to create a new instance of CL-WOL.CORE:MAGIC-PACKET.

CL-USER> (defparameter *magic-packet*
           (cl-wol.core:make-magic-packet "aa:bb:cc:dd:ee:ff"))
*MAGIC-PACKET*

The CL-WOL.CORE:MAKE-MAGIC-PACKET function accepts an optional second argument, which represents a SecureOn password. The format of the SecureOn password is the same as the one for MAC addresses. For example, if you need to create a magic packet with SecureOn password appended to the payload you can evaluate the following expression.

CL-USER> (defparameter *magic-packet*
           (cl-wol.core:make-magic-packet "aa:bb:cc:dd:ee:ff" "00-00-00-00-00-00"))
*MAGIC-PACKET*

Another way to create a magic packet is by providing a (simple-array (unsigned-byte 8) (6) vector to CL-WOL.CORE:MAKE-MAGIC-PACKET. You can also use the CL-WOL.CORE:MAKE-OCTET-VECTOR function to create a new octet vector. For example.

CL-USER> (defparameter *magic-packet*
           (cl-wol.core:make-magic-packet (cl-wol.core:make-octet-vector #(1 2 3 4 5 6))))
*MAGIC-PACKET*

Now that we have a magic packet we can broadcast it to a given port and address. In order to do that we will use the CL-WOL.CORE:WAKE generic function. The following example broadcasts the magic packet to 255.255.255.255 on port 7.

CL-USER> (cl-wol.core:wake *magic-packet* "255.255.255.255" 7)
T

CLI

./images/wol-demo.gif

You can build the CLI application of cl-wol by executing the following command.

make cli

The default Lisp implementation is SBCL, so if you are using a different implementation simply pass the LISP environment variable before invoking the cli target. This command builds the CLI application using Clozure Common Lisp for example.

LISP=ccl make cli

Once the app is built you can find the executable in the bin directory of the cl-wol.cli system, which you can later install somewhere in your PATH, e.g.

sudo install ./bin/wol /usr/local/bin

You can also generate Zsh completions for the CLI application by executing the wol zsh-completions sub-command, e.g.

wol zsh-completions > ~/.zsh-completions/_wol

You can wake up remote systems by using the wol wake sub-command. Multiple MAC addresses can be specified on the command-line as separate arguments, e.g.

$ wol wake 00:01:02:03:04:05 aa:bb:cc:dd:ee:ff
Waking up 00:01:02:03:04:05 ...
Waking up aa:bb:cc:dd:ee:ff ...

Instead of remembering MAC addresses by heart the cl-wol CLI application supports storing MAC addresses in a local SQLite database, which can be looked up by the various sub-commands.

First, we need to initialize a new database file using the wol init-db sub-command.

$ wol init-db --database wol.db
 <INFO> [14:25:36] cl-migratum.core core.lisp (apply-pending) -
  Found 1 pending migration(s) to be applied
 <INFO> [14:25:36] cl-migratum.core core.lisp (apply-and-register) -
  Applying migration 20211222183337 - add_hosts_table

Once the database is initialized you can add hosts to it. For example:

wol add-host --database wol.db --address aa:bb:cc:dd:ee:ff --name box-01
wol add-host --database wol.db --address 01:02:03:04:05:06 --name box-02

Listing the hosts from the database is done via the wol list-hosts sub-command.

$ wol list-hosts --database wol.db
+----+--------+-------------------+---------------------+
| ID | NAME   | ADDR              | CREATED AT          |
+----+--------+-------------------+---------------------+
|  1 | box-01 | aa:bb:cc:dd:ee:ff | 2021-12-26 14:27:19 |
|  2 | box-02 | 01:02:03:04:05:06 | 2021-12-26 14:27:30 |
+----+--------+-------------------+---------------------+

You can now wake up hosts by referring to their names. In order to do that use the --database and --name options of the wol wake sub-command. The --name option can be repeated multiple times in order to refer to different hosts, e.g.

$ wol wake --database wol.db --name box-01 --name box-02
Waking up 01:02:03:04:05:06 ...
Waking up aa:bb:cc:dd:ee:ff ...

Deleting hosts from the database is done via the wol delete-host sub-command, e.g.

wol delete-host --database wol.db box-01 box-02

Tests

Tests are provided as part of the :cl-wol.test system.

In order to run the tests you can evaluate the following expressions from your Lisp REPL.

CL-USER> (ql:quickload :cl-wol.test)
CL-USER> (asdf:test-system :cl-wol.test)

Or you can run the tests using the test target instead, e.g.

make test

Here’s how to run the tests against SBCL, CCL and ECL for example.

for lisp in sbcl ccl ecl; do
    echo "Running tests using ${lisp} ..."
    LISP=${lisp} make test > ${lisp}-tests.out
done

Docker Images

You can build and run a Docker image of the CLI application by executing the following commands.

docker build -t cl-wol.cli:latest -f Dockerfile .

A separate image can be built for running the test suite of cl-wol.

docker build -t cl-wol.test:latest -f Dockerfile.tests .
docker run --rm cl-wol.test:latest

Contributing

cl-wol is hosted on Github. Please contribute by reporting issues, suggesting features or by sending patches using pull requests.

License

This project is Open Source and licensed under the BSD License.

Authors

Releases

No releases published

Sponsor this project

 

Packages

No packages published