Refactor send_wol function to streamline magic packet creation and enforce IPv4 UDP socket binding
This commit is contained in:
@@ -43,37 +43,27 @@ local function mac_to_bytes(mac)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function send_wol(mac_str, bcast_ip, port)
|
local function send_wol(mac_str, bcast_ip, port)
|
||||||
local mb = mac_to_bytes(mac_str)
|
-- Build magic packet
|
||||||
if not mb then return false, "invalid MAC" end
|
local bytes = {}
|
||||||
local packet = string.rep(string.char(0xFF), 6) .. mb:rep(16)
|
for byte in mac_str:gmatch("(%x%x)") do table.insert(bytes, tonumber(byte, 16)) end
|
||||||
|
if #bytes ~= 6 then return false, "invalid MAC" end
|
||||||
|
local mac = string.char(table.unpack(bytes))
|
||||||
|
local packet = string.rep(string.char(0xFF), 6) .. mac:rep(16)
|
||||||
|
|
||||||
-- 1) Force an IPv4 UDP socket (fallback to udp() if udp4() is not available)
|
-- Create IPv4 UDP socket (udp4 if available), bind to IPv4 wildcard to lock AF_INET
|
||||||
local udp_ctor = socket.udp4 or socket.udp
|
local udp = assert((socket.udp4 or socket.udp)())
|
||||||
local udp = assert(udp_ctor())
|
|
||||||
udp:settimeout(2)
|
udp:settimeout(2)
|
||||||
|
assert(udp:setsockname("0.0.0.0", 0)) -- force IPv4 family
|
||||||
|
assert(udp:setoption("broadcast", true)) -- allow broadcast
|
||||||
|
|
||||||
-- 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
|
|
||||||
|
|
||||||
-- 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)
|
local ok, err = udp:sendto(packet, bcast_ip, port)
|
||||||
|
|
||||||
udp:close()
|
udp:close()
|
||||||
if not ok then return false, err end
|
return ok ~= nil, err
|
||||||
return true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- Kept for reference; not used to keep parity with your minimal bash
|
-- Kept for reference; not used to keep parity with your minimal bash
|
||||||
-- local function port_is_up(host, port, timeout_sec)
|
-- local function port_is_up(host, port, timeout_sec)
|
||||||
-- local deadline = socket.gettime() + (timeout_sec or 1)
|
-- local deadline = socket.gettime() + (timeout_sec or 1)
|
||||||
|
|||||||
Reference in New Issue
Block a user