diff options
author | Jo-Philipp Wich <jo@mein.io> | 2018-03-12 16:12:18 +0100 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2018-03-12 16:12:18 +0100 |
commit | 28e3b328545529c19429ce88c7d1769e64e2de0f (patch) | |
tree | 3d7d85d7d4d1202199bad98df125f2af88b73c86 /applications | |
parent | dfba318140e1a84359e221b7a9154337595dbded (diff) |
treewide: unify mac address handling
Use the new luci.ip MAC address facilities to parse and verify MAC addresses
in a common way, instead of relying on various ad-hoc solutions.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'applications')
4 files changed, 80 insertions, 101 deletions
diff --git a/applications/luci-app-olsr/luasrc/controller/olsr.lua b/applications/luci-app-olsr/luasrc/controller/olsr.lua index 0564bd4ea..229f3d61b 100644 --- a/applications/luci-app-olsr/luasrc/controller/olsr.lua +++ b/applications/luci-app-olsr/luasrc/controller/olsr.lua @@ -101,41 +101,19 @@ end local function local_mac_lookup(ipaddr) - local _, ifa, dev - - ipaddr = tostring(ipaddr) - - if not ifaddr_table then - ifaddr_table = nixio.getifaddrs() - end - - -- ipaddr -> ifname - for _, ifa in ipairs(ifaddr_table) do - if ifa.addr == ipaddr then - dev = ifa.name - break - end - end - - -- ifname -> macaddr - for _, ifa in ipairs(ifaddr_table) do - if ifa.name == dev and ifa.family == "packet" then - return ifa.addr - end + local _, rt + for _, rt in ipairs(luci.ip.routes({ type = 1, src = ipaddr })) do + local link = rt.dev and luci.ip.link(rt.dev) + local mac = link and luci.ip.checkmac(link.mac) + if mac then return mac end end end local function remote_mac_lookup(ipaddr) local _, n - - if not neigh_table then - neigh_table = luci.ip.neighbors() - end - - for _, n in ipairs(neigh_table) do - if n.mac and n.dest and n.dest:equal(ipaddr) then - return n.mac - end + for _, n in ipairs(luci.ip.neighbors({ dest = ipaddr })) do + local mac = luci.ip.checkmac(n.mac) + if mac then return mac end end end @@ -201,9 +179,9 @@ function action_neigh(json) for _, val in ipairs(assoclist) do if val.network == interface and val.list then + local assocmac, assot for assocmac, assot in pairs(val.list) do - assocmac = string.lower(assocmac or "") - if rmac == assocmac then + if rmac == luci.ip.checkmac(assocmac) then signal = tonumber(assot.signal) noise = tonumber(assot.noise) snr = (noise*-1) - (signal*-1) diff --git a/applications/luci-app-splash/luasrc/controller/splash/splash.lua b/applications/luci-app-splash/luasrc/controller/splash/splash.lua index 13b8edce6..b4fdbd53a 100644 --- a/applications/luci-app-splash/luasrc/controller/splash/splash.lua +++ b/applications/luci-app-splash/luasrc/controller/splash/splash.lua @@ -2,6 +2,7 @@ module("luci.controller.splash.splash", package.seeall) local uci = luci.model.uci.cursor() local util = require "luci.util" +local ipc = require "luci.ip" function index() entry({"admin", "services", "splash"}, cbi("splash/splash"), _("Client-Splash"), 90) @@ -24,30 +25,35 @@ function index() end function ip_to_mac(ip) - local ipc = require "luci.ip" local i, n - - for i, n in ipairs(ipc.neighbors()) do - if n.mac and n.dest and n.dest:equal(ip) then - return n.mac - end + for i, n in ipairs(ipc.neighbors({ dest = ip })) do + local mac = ipc.checkmac(n.mac) + if mac then return mac end end end function action_dispatch() local uci = luci.model.uci.cursor_state() - local mac = ip_to_mac(luci.http.getenv("REMOTE_ADDR")) or "" + local mac = ip_to_mac(luci.http.getenv("REMOTE_ADDR")) local access = false - uci:foreach("luci_splash", "lease", function(s) - if s.mac and s.mac:lower() == mac then access = true end - end) + if mac then + uci:foreach("luci_splash", "lease", function(s) + if ipc.checkmac(s.mac) == mac then + access = true + return false + end + end) - uci:foreach("luci_splash", "whitelist", function(s) - if s.mac and s.mac:lower() == mac then access = true end - end) + uci:foreach("luci_splash", "whitelist", function(s) + if ipc.checkmac(s.mac) == mac then + access = true + return false + end + end) + end - if #mac > 0 and access then + if access then luci.http.redirect(luci.dispatcher.build_url()) else luci.http.redirect(luci.dispatcher.build_url("splash", "splash")) @@ -56,33 +62,39 @@ end function blacklist() leased_macs = { } - uci:foreach("luci_splash", "blacklist", - function(s) leased_macs[s.mac:lower()] = true + uci:foreach("luci_splash", "blacklist", function(s) + local m = ipc.checkmac(s.mac) + if m then leased_macs[m] = true end end) return leased_macs end function action_activate() local ipc = require "luci.ip" - local mac = ip_to_mac(luci.http.getenv("REMOTE_ADDR") or "127.0.0.1") or "" + local mac = ip_to_mac(luci.http.getenv("REMOTE_ADDR") or "127.0.0.1") local uci_state = require "luci.model.uci".cursor_state() local blacklisted = false if mac and luci.http.formvalue("accept") then - uci:foreach("luci_splash", "blacklist", - function(s) if s.mac and s.mac:lower() == mac then blacklisted = true end + uci:foreach("luci_splash", "blacklist", function(s) + if ipc.checkmac(s.mac) == mac then + blacklisted = true + return false + end end) + if blacklisted then luci.http.redirect(luci.dispatcher.build_url("splash" ,"blocked")) else + local id = tostring(mac):gsub(':', ''):lower() local redirect_url = uci:get("luci_splash", "general", "redirect_url") if not redirect_url then - redirect_url = uci_state:get("luci_splash_locations", mac:gsub(':', ''):lower(), "location") + redirect_url = uci_state:get("luci_splash_locations", id, "location") end if not redirect_url then redirect_url = luci.model.uci.cursor():get("freifunk", "community", "homepage") or 'http://www.freifunk.net' end - remove_redirect(mac:gsub(':', ''):lower()) - os.execute("luci-splash lease "..mac.." >/dev/null 2>&1") + remove_redirect(id) + os.execute("luci-splash lease "..tostring(mac).." >/dev/null 2>&1") luci.http.redirect(redirect_url) end else @@ -101,6 +113,7 @@ function action_status_admin() remove = { } } + local key, _ for key, _ in pairs(macs) do local policy = luci.http.formvalue("policy.%s" % key) local mac = luci.http.protocol.urldecode(key) @@ -141,17 +154,17 @@ function action_status_public() luci.template.render("admin_status/splash", { is_admin = false }) end -function remove_redirect(mac) - local mac = mac:lower() - mac = mac:gsub(":", "") +function remove_redirect(id) local uci = require "luci.model.uci".cursor_state() local redirects = uci:get_all("luci_splash_locations") --uci:load("luci_splash_locations") uci:revert("luci_splash_locations") + -- For all redirects + local k, v for k, v in pairs(redirects) do if v[".type"] == "redirect" then - if v[".name"] ~= mac then + if v[".name"] ~= id then -- Rewrite state uci:section("luci_splash_locations", "redirect", v[".name"], { location = v.location @@ -159,5 +172,6 @@ function remove_redirect(mac) end end end + uci:save("luci_splash_redirects") end diff --git a/applications/luci-app-splash/luasrc/view/admin_status/splash.htm b/applications/luci-app-splash/luasrc/view/admin_status/splash.htm index 3415c205d..37f67776a 100644 --- a/applications/luci-app-splash/luasrc/view/admin_status/splash.htm +++ b/applications/luci-app-splash/luasrc/view/admin_status/splash.htm @@ -6,6 +6,8 @@ <%- local utl = require "luci.util" +local sys = require "luci.sys" +local ipc = require "luci.ip" local ipt = require "luci.sys.iptparser".IptParser() local uci = require "luci.model.uci".cursor_state() local wat = require "luci.tools.webadmin" @@ -14,21 +16,15 @@ local fs = require "nixio.fs" local clients = { } local leasetime = tonumber(uci:get("luci_splash", "general", "leasetime") or 1) * 60 * 60 -local leasefile = "/tmp/dhcp.leases" - -uci:foreach("dhcp", "dnsmasq", - function(s) - if s.leasefile then leasefile = s.leasefile end - end) - uci:foreach("luci_splash_leases", "lease", function(s) - if s.start and s.mac then - clients[s.mac:lower()] = { + local m = ipc.checkmac(s.mac) + if m and s.start then + clients[m] = { start = tonumber(s.start), limit = ( tonumber(s.start) + leasetime ), - mac = s.mac:upper(), + mac = m, ipaddr = s.ipaddr, policy = "normal", packets = 0, @@ -39,11 +35,12 @@ uci:foreach("luci_splash_leases", "lease", for _, r in ipairs(ipt:find({table="nat", chain="luci_splash_leases"})) do if r.options and #r.options >= 2 and r.options[1] == "MAC" then - if not clients[r.options[2]:lower()] then - clients[r.options[2]:lower()] = { + local m = ipc.checkmac(r.options[2]) + if m and not clients[m] then + clients[m] = { start = 0, limit = 0, - mac = r.options[2]:upper(), + mac = m, policy = ( r.target == "RETURN" ) and "whitelist" or "blacklist", packets = 0, bytes = 0 @@ -60,7 +57,7 @@ for mac, client in pairs(clients) do if client.ipaddr then local rin = ipt:find({table="mangle", chain="luci_splash_mark_in", destination=client.ipaddr}) - local rout = ipt:find({table="mangle", chain="luci_splash_mark_out", options={"MAC", client.mac:upper()}}) + local rout = ipt:find({table="mangle", chain="luci_splash_mark_out", options={"MAC", client.mac}}) if rin and #rin > 0 then client.bytes_in = rin[1].bytes @@ -76,39 +73,27 @@ end uci:foreach("luci_splash", "whitelist", function(s) - if s.mac and clients[s.mac:lower()] then - clients[s.mac:lower()].policy="whitelist" + local m = ipc.checkmac(s.mac) + if m and clients[m] then + clients[m].policy="whitelist" end end) uci:foreach("luci_splash", "blacklist", function(s) - if s.mac and clients[s.mac:lower()] then - clients[s.mac:lower()].policy=(s.kicked and "kicked" or "blacklist") + local m = ipc.checkmac(s.mac) + if m and clients[m] then + clients[m].policy=(s.kicked and "kicked" or "blacklist") end end) -if fs.access(leasefile) then - for l in io.lines(leasefile) do - local time, mac, ip, name = l:match("^(%d+) (%S+) (%S+) (%S+)") - if time and mac and ip then - local c = clients[mac:lower()] - if c then - c.ip = ip - c.hostname = ( name ~= "*" ) and name or nil - end - end +sys.net.host_hints(function(mac, v4, v6, name) + local c = mac and clients[mac] + if c then + c.ip = c.ip or v4 + c.hostname = c.hostname or name end -end - -for i, n in ipairs(ipc.neighbors({ family = 4 })) do - if n.mac and n.dest then - local c = clients[n.mac] - if c and not c.ip then - c.ip = n.dest:string() - end - end -end +end) local function showmac(mac) if not is_admin then @@ -176,7 +161,7 @@ end splash.hostname, splash.ip, splash.mac, splash.timeleft, splash.trafficin, splash.trafficout); <% if is_admin then %> - s += String.format('<select name="policy.%s" style="width:200px">', splash.mac.toLowerCase()); + s += String.format('<select name="policy.%s" style="width:200px">', splash.mac); if (splash.policy == 'whitelist') { s += '<option value="whitelist" selected="selected"><%:whitelisted%></option>' } else { @@ -196,7 +181,7 @@ end s += String.format( '</select>' + '<input type="submit" class="cbi-button cbi-button-save" name="save.%s" value="<%:Save%>" />', - splash.mac.toLowerCase()); + splash.mac); <% else %> s += String.format('%s', splash.policy); <% end %> diff --git a/applications/luci-app-wol/luasrc/model/cbi/wol.lua b/applications/luci-app-wol/luasrc/model/cbi/wol.lua index ec6a1be2a..d40dde017 100644 --- a/applications/luci-app-wol/luasrc/model/cbi/wol.lua +++ b/applications/luci-app-wol/luasrc/model/cbi/wol.lua @@ -2,6 +2,7 @@ -- Licensed to the public under the Apache License 2.0. local sys = require "luci.sys" +local ipc = require "luci.ip" local fs = require "nixio.fs" m = SimpleForm("wol", translate("Wake on LAN"), @@ -58,7 +59,8 @@ end function host.write(self, s, val) local host = luci.http.formvalue("cbid.wol.1.mac") - if host and #host > 0 and host:match("^[a-fA-F0-9:]+$") then + local mac = ipc.checkmac(host) + if mac then local cmd local util = luci.http.formvalue("cbid.wol.1.binary") or ( has_ewk and "/usr/bin/etherwake" or "/usr/bin/wol" @@ -69,10 +71,10 @@ function host.write(self, s, val) local broadcast = luci.http.formvalue("cbid.wol.1.broadcast") cmd = "%s -D%s %s %q" %{ util, (iface ~= "" and " -i %q" % iface or ""), - (broadcast == "1" and " -b" or ""), host + (broadcast == "1" and " -b" or ""), mac } else - cmd = "%s -v %q" %{ util, host } + cmd = "%s -v %q" %{ util, mac } end local msg = "<p><strong>%s</strong><br /><br /><code>%s<br /><br />" %{ |