#!/opt/lnxall_app/bin/lua local bit = require "bit" local uci = require "uci" local invoker = require "invoker" local posix = require "posix" local giface, gmac, gval = arg[1], arg[2], arg[3] local gmac_val = nil local function usage() local iou = io.stderr iou:write("Usage: uci_set_mac wan1 MAC-ADDRESS [1]\n") iou:flush() os.exit(1) end local function validate_args() if type(giface) ~= "string" or #giface == 0 then usage() end if type(gmac) ~= "string" or #gmac ~= 17 then io.stderr:write("Error, invalid MAC address\n") usage() end local mval = {} for byte in string.gmatch(gmac, "[^:]+") do local num = tonumber("0x" .. byte) if not num or num < 0 or num > 255 then io.stderr:write(string.format("Error, invalid MAC address: %s\n", gmac)) usage() end mval[#mval + 1] = num end if #mval ~= 6 then io.stderr:write(string.format("Error, invalid MAC address: %s\n", gmac)) usage() end gmac_val = mval if type(gval) == "string" and #gval > 0 then local val = tonumber(gval) if type(val) ~= "number" or val ~= math.floor(val) or val < -255 or val > 255 then io.stderr:write(string.format("Error, invalid substruct/addition argument: %s\n", gval)) usage() end gval = val else gval = 0 end return true end local function modify_macaddr() local newmac = gmac if gval ~= 0 then local nval = gmac_val for idx = 6, 1, -1 do nval[idx] = nval[idx] + gval if nval[idx] < 0 then gval = -1 nval[idx] = bit.band(nval[idx], 0xff) elseif nval[idx] > 255 then gval = 1 nval[idx] = bit.band(nval[idx], 0xff) else break end end newmac = string.format("%02x:%02x:%02x:%02x:%02x:%02x", nval[1], nval[2], nval[3], nval[4], nval[5], nval[6]) io.stdout:write(string.format("Computed modified MAC address: %s\n", newmac)) io.stdout:flush() end local okay, nminfo = invoker.invoke(invoker.OUTPUT + invoker.NOSTDIO + 0x70000, "nmcli", "con", "show", giface) if okay ~= 0 or type(nminfo) ~= "string" then nminfo = "" end local nuci = uci.cursor("/etc/config") if nuci:get("network", giface) == nil then nuci:close(); nuci = nil os.exit(2) end local oldmac = nuci:get("network", giface, "macaddr") if oldmac == newmac and string.find(nminfo, newmac, 1, true) then nuci:close(); nuci = nil os.exit(3) end io.stdout:write(string.format("Updating interface %s with MAC address: %s\n", giface, newmac)) io.stdout:flush() nuci:set("network", giface, "macaddr", newmac) nuci:commit("network") nuci:close(); nuci = nil -- invoker.invoke(0, "nothup", "/bin/sh", "-c", "sleep 3 ; netuci") return true end posix.setenv("PATH", "/opt/lnxall_app/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin", true) validate_args() modify_macaddr() os.exit(0)