Fix WoL: target the device's subnet directed broadcast instead of spraying all NICs - #597
Open
nsoto-development wants to merge 2 commits into
Open
Conversation
…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
marked this pull request as draft
July 26, 2026 17:06
nsoto-development
marked this pull request as ready for review
July 27, 2026 00:35
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
WolService.WakeFunctionToAllNicssends 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..255for 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.