I run four Lenovo ThinkCentre Tinys (three M700s and an M900): two Proxmox hosts, the box that runs my NVR, and a Proxmox cold spare. The spare stays powered off until it’s needed, and my notes described it as “powered off in Wake-on-LAN standby”. I wanted to read its CPU model, so I tried to wake it. Nothing happened.

Sending the magic packet

A Wake-on-LAN magic packet is six 0xff bytes followed by the target MAC address repeated 16 times, broadcast over UDP. You don’t need a dedicated tool; Python’s standard library is enough. Run it from a machine on the same LAN segment, because routers don’t forward these broadcasts by default:

import socket

mac = bytes.fromhex("aabbccddeeff")          # target MAC, no separators
packet = b"\xff" * 6 + mac * 16

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
for port in (9, 7):                           # the two usual WoL ports
    s.sendto(packet, ("<lan-broadcast>", port))   # e.g. x.x.x.255

I waited four minutes for SSH to come up. It never did, and the machine didn’t answer ping either.

Finding the MAC of a machine that’s off

Before blaming the packet, I needed to be sure I had the right MAC address. The spare uses a static IP, so there was no DHCP reservation recording it. A machine that’s switched off can’t tell you its own MAC, but other machines remember it. Stale ARP entries on the router and on other hosts still hold it:

ip neigh show <spare-ip>
# <spare-ip> dev vmbr0 lladdr <mac> STALE

I also keep a topology graph of the LAN that stores each IP with its MAC. When the router’s ARP cache, a Proxmox host’s ARP cache and the graph all agreed, I was confident the MAC was right and the problem was on the machine itself.

Checking Wake-on-LAN from the OS

On the Tinys that were running, ethtool shows both what the network card supports and what’s currently enabled:

ethtool eno1 | grep -i wake
#   Supports Wake-on: pumbg
#   Wake-on: g

The letters are flags: p wake on PHY activity, u unicast, m multicast, b broadcast, g magic packet, and d means disabled. Wake-on: g is the setting you want. Both running Proxmox hosts already showed g.

The NVR box didn’t have ethtool installed. sysfs still gives a partial answer:

cat /sys/class/net/eno1/device/power/wakeup
# enabled

That only means the PCI device is allowed to wake the system. It doesn’t tell you which wake mode the network card is set to. To see that, install ethtool.

Neither check tells you anything about the BIOS. On these Lenovos, Wake-on-LAN also has to be enabled in the firmware, and Linux reporting Wake-on: g doesn’t prove the firmware will keep the network card powered once the machine is off.

The switch port tells the truth

The most useful check was the one I almost skipped: the switch port. A machine with Wake-on-LAN armed keeps its network card powered while it’s off, so the link stays up, usually at a lower speed. If the port is down while the machine is off, the card has no power and can’t hear any magic packet.

Most managed switches report port state over SNMP. Interface status is ifOperStatus (1 = up, 2 = down). Using the numeric OID means you don’t need any MIB files installed:

snmpget -v2c -c <community> -Oqv <switch> .1.3.6.1.2.1.2.2.1.2.<port>   # ifDescr
snmpget -v2c -c <community> -Oqv <switch> .1.3.6.1.2.1.2.2.1.8.<port>   # ifOperStatus
# "GigabitEthernet<port>"
# 2

The spare’s port was down. So either Wake-on-LAN was never enabled in its BIOS, or the machine isn’t plugged in. Either way, “Wake-on-LAN standby” was wishful documentation.

The fix (BIOS first, then the OS)

On ThinkCentre M700 and M900 Tinys, press F1 at the Lenovo logo to open setup, then go to Power → Automatic Power On → Wake on LAN and set it to Primary (or Enabled). Save and exit.

Then make sure Linux leaves magic-packet wake turned on. Some drivers and distributions reset it at boot, so set it every time the interface comes up. On Proxmox, which uses ifupdown2, add a post-up line under the physical interface in /etc/network/interfaces:

iface eno1 inet manual
        post-up /usr/sbin/ethtool -s eno1 wol g

Then test it properly: shut the machine down, confirm the switch port stays up, and wake it from another host.

Gotchas, collected

  • Documentation drifts. “It’s in WoL standby” had never actually been tested. Doing one real wake is the only proof.
  • Wake-on: g in Linux is necessary but not sufficient. The firmware decides whether the network card gets standby power.
  • /sys/.../power/wakeup isn’t the WoL mode. It’s a permission flag on the PCI device. Use ethtool for the real setting.
  • The switch port’s link state is the best single check. Down while the machine is off means it can’t be woken, whatever Linux says.
  • Off machines have no DHCP lease to look up. Get the MAC from stale ARP entries on other hosts before the cache ages out, and write it down.
  • Send from the same LAN segment. Magic packets are broadcasts; across a router you need a directed broadcast or a relay.

Right now two of the four Tinys show Wake-on: g in Linux, one needs ethtool installed before I can tell, and the cold spare definitely can’t be woken until I change its BIOS setting in person. I’ve replaced the vague “standby” note with a per-machine checklist, and each one gets ticked off only after a real wake from power-off.