Skip to content

Fix WoL: target the device's subnet directed broadcast instead of spraying all NICs - #597

Open
nsoto-development wants to merge 2 commits into
Maassoft:masterfrom
nsoto-development:fix/wol-subnet-directed-broadcast
Open

Fix WoL: target the device's subnet directed broadcast instead of spraying all NICs#597
nsoto-development wants to merge 2 commits into
Maassoft:masterfrom
nsoto-development:fix/wol-subnet-directed-broadcast

Conversation

@nsoto-development

@nsoto-development nsoto-development commented Jul 23, 2026

Copy link
Copy Markdown

Problem

WolService.WakeFunctionToAllNics sends the Wake-on-LAN magic packet out of every network interface. When a VPN virtual adapter is present (e.g. Proton VPN), packets get sourced from the VPN adapter and routed into the tunnel, so they never reach a device on a directly-connected LAN subnet, and the wake silently fails.

There is also a second, latent bug: for each interface the "broadcast" address was computed by setting the last octet to 0 (x.x.x.0) — that is the network address, not the directed broadcast, and it hardcodes a /24. The wake only worked at all because the separate limited broadcast (255.255.255.255) happened to leave the correct NIC when no VPN was competing for the route.

Fix

When the target device's IP is known, select the local interface whose subnet actually contains the target (using each address's real PrefixLength) and send the magic packet bound to that interface, using that subnet's correct directed broadcast (e.g. .255 for a /24). Interfaces on other subnets — including VPN adapters — are no longer used.

The all-interfaces broadcast is kept as a fallback for when the target IP is unknown or no local interface shares its subnet, and that fallback now also computes the directed broadcast correctly from the prefix length instead of using the network address.

The change is split into two commits: the directed-broadcast computation fix, then the subnet-aware interface selection.

Testing

Verified on a machine with a wired NIC and a wireless NIC on different private subnets plus a VPN virtual adapter. For a target device on the wired NIC's subnet, the code now selects that interface and sends the directed broadcast for that subnet only, excluding the VPN and wireless adapters. Confirmed end-to-end by waking a real LG webOS TV from standby.

Even with these fixes, ColorControl very rarely started working end-to-end for WoL in my case. Ended up writing a whole stand-alone prototype for handling the WoL independently: https://github.com/nsoto-development/lgtv-display-sync

In the mean time, these changes fix real bugs and work towards the larger fix as demonstrated in the linked repo. As I have more time, once these fixes are merged, I can spend further time trying to resolve the outstanding issue with dropped WS connection.

…k address

WakeFunctionToAllNics computed the per-interface broadcast by setting the
last octet to 0 (x.x.x.0), which is the network address rather than the
directed broadcast, and hardcoded a /24. Compute the directed broadcast from
the interface's actual prefix length instead (e.g. 192.168.100.255 for a /24).
…NICs

WakeFunctionToAllNics broadcast the magic packet out of every network
interface. With a VPN virtual adapter present (e.g. Proton VPN), packets were
sourced from the VPN adapter and routed into the tunnel, so they never reached
a device on a directly-connected LAN subnet.

When the target device's IP is known, select the local interface whose subnet
contains the target (using its actual prefix length) and send bound to that
interface using the subnet's directed broadcast. Other interfaces, including
VPN adapters, are no longer used. The all-interfaces broadcast is kept as a
fallback for when the target IP is unknown or no local interface shares its
subnet.
@nsoto-development
nsoto-development marked this pull request as draft July 26, 2026 17:06
@nsoto-development
nsoto-development marked this pull request as ready for review July 27, 2026 00:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant