Enhance Wake-on-LAN functionality by forcing IPv4 UDP socket and adding source IP binding

This commit is contained in:
Bastian (BaM)
2025-09-14 11:08:40 +02:00
parent 8b32856c0d
commit c57359daef

View File

@@ -47,25 +47,33 @@ local function send_wol(mac_str, bcast_ip, port)
if not mb then return false, "invalid MAC" end
local packet = string.rep(string.char(0xFF), 6) .. mb:rep(16)
local udp = assert(socket.udp())
-- 1) Force an IPv4 UDP socket (fallback to udp() if udp4() is not available)
local udp_ctor = socket.udp4 or socket.udp
local udp = assert(udp_ctor())
udp:settimeout(2)
-- Optional: bind to a specific source IP (helps in host network with multi-NIC)
local WOL_SRC_IP = os.getenv("WOL_SRC_IP")
if WOL_SRC_IP and WOL_SRC_IP ~= "" then
assert(udp:setsockname(WOL_SRC_IP, 0))
-- 2) Bind to an IPv4 source to lock the address family
-- If you have WOL_SRC_IP set, bind to that; otherwise 0.0.0.0.
local src_ip = os.getenv("WOL_SRC_IP")
if src_ip and src_ip ~= "" then
assert(udp:setsockname(src_ip, 0))
else
assert(udp:setsockname("0.0.0.0", 0))
end
-- IMPORTANT: must be true or Linux will return EACCES on broadcast sendto()
-- 3) Enable broadcast. This will fail on AF_INET6, so do it *after* binding IPv4.
assert(udp:setoption("broadcast", true))
-- 4) Send to directed broadcast (recommended) or 255.255.255.255 if you must.
local ok, err = udp:sendto(packet, bcast_ip, port)
udp:close()
if not ok then return false, err end
return true
end
-- Kept for reference; not used to keep parity with your minimal bash
-- local function port_is_up(host, port, timeout_sec)
-- local deadline = socket.gettime() + (timeout_sec or 1)