treewide: unify mac address handling
authorJo-Philipp Wich <jo@mein.io>
Mon, 12 Mar 2018 15:12:18 +0000 (16:12 +0100)
committerJo-Philipp Wich <jo@mein.io>
Mon, 12 Mar 2018 15:12:18 +0000 (16:12 +0100)
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>
13 files changed:
applications/luci-app-olsr/luasrc/controller/olsr.lua
applications/luci-app-splash/luasrc/controller/splash/splash.lua
applications/luci-app-splash/luasrc/view/admin_status/splash.htm
applications/luci-app-wol/luasrc/model/cbi/wol.lua
modules/luci-base/luasrc/cbi/datatypes.lua
modules/luci-base/luasrc/model/network.lua
modules/luci-base/luasrc/sys.lua
modules/luci-base/luasrc/tools/status.lua
modules/luci-mod-admin-full/luasrc/controller/admin/network.lua
modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/dhcp.lua
modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/hosts.lua
modules/luci-mod-admin-full/luasrc/view/admin_status/routes.htm
modules/luci-mod-admin-mini/luasrc/model/cbi/mini/dhcp.lua

index 0564bd4..229f3d6 100644 (file)
@@ -101,41 +101,19 @@ end
 
 
 local function local_mac_lookup(ipaddr)
 
 
 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
        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
 
        end
 end
 
@@ -201,9 +179,9 @@ function action_neigh(json)
 
                for _, val in ipairs(assoclist) do
                        if val.network == interface and val.list then
 
                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
                                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)
                                                signal = tonumber(assot.signal)
                                                noise = tonumber(assot.noise)
                                                snr = (noise*-1) - (signal*-1)
index 13b8edc..b4fdbd5 100644 (file)
@@ -2,6 +2,7 @@ module("luci.controller.splash.splash", package.seeall)
 
 local uci = luci.model.uci.cursor()
 local util = require "luci.util"
 
 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)
 
 function index()
        entry({"admin", "services", "splash"}, cbi("splash/splash"), _("Client-Splash"), 90)
@@ -24,30 +25,35 @@ function index()
 end
 
 function ip_to_mac(ip)
 end
 
 function ip_to_mac(ip)
-       local ipc = require "luci.ip"
        local i, n
        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()
        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
 
        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"))
                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 = { }
 
 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"
        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
        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)
                end)
+
                if blacklisted then     
                        luci.http.redirect(luci.dispatcher.build_url("splash" ,"blocked"))
                else
                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
                        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
                        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
                        luci.http.redirect(redirect_url)
                end
        else
@@ -101,6 +113,7 @@ function action_status_admin()
                remove    = { }
        }
 
                remove    = { }
        }
 
+       local key, _
        for key, _ in pairs(macs) do
                local policy = luci.http.formvalue("policy.%s" % key)
                local mac    = luci.http.protocol.urldecode(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
 
        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")
        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
        -- For all redirects
+       local k, v
        for k, v in pairs(redirects) do
                if v[".type"] == "redirect" then
        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
                                -- Rewrite state
                                uci:section("luci_splash_locations", "redirect", v[".name"], {
                                        location = v.location
@@ -159,5 +172,6 @@ function remove_redirect(mac)
                        end
                end
        end
                        end
                end
        end
+
        uci:save("luci_splash_redirects")
 end
        uci:save("luci_splash_redirects")
 end
index 3415c20..37f6777 100644 (file)
@@ -6,6 +6,8 @@
 <%-
 
 local utl = require "luci.util"
 <%-
 
 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"
 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 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)
 
 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 ),
                                start   = tonumber(s.start),
                                limit   = ( tonumber(s.start) + leasetime ),
-                               mac     = s.mac:upper(),
+                               mac     = m,
                                ipaddr  = s.ipaddr,
                                policy  = "normal",
                                packets = 0,
                                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
 
 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,
                                start  = 0,
                                limit  = 0,
-                               mac    = r.options[2]:upper(),
+                               mac    = m,
                                policy = ( r.target == "RETURN" ) and "whitelist" or "blacklist",
                                packets = 0,
                                bytes   = 0
                                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})
 
        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
 
                if rin and #rin > 0 then
                        client.bytes_in   = rin[1].bytes
@@ -76,39 +73,27 @@ end
 
 uci:foreach("luci_splash", "whitelist",
        function(s)
 
 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)
                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)            
 
                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
-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
 
 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 %>
                                                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 {
                                        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%>" />',
                                        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 %>
                                <% else %>
                                        s += String.format('%s', splash.policy);
                                <% end %>
index ec6a1be..d40dde0 100644 (file)
@@ -2,6 +2,7 @@
 -- Licensed to the public under the Apache License 2.0.
 
 local sys = require "luci.sys"
 -- 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"),
 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")
 
 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"
                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 ""),
                        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
                        }
                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 />" %{
                end
 
                local msg = "<p><strong>%s</strong><br /><br /><code>%s<br /><br />" %{
index a7e02f3..55cdf8a 100644 (file)
@@ -196,23 +196,7 @@ function portrange(val)
 end
 
 function macaddr(val)
 end
 
 function macaddr(val)
-       if val and val:match(
-               "^[a-fA-F0-9]+:[a-fA-F0-9]+:[a-fA-F0-9]+:" ..
-                "[a-fA-F0-9]+:[a-fA-F0-9]+:[a-fA-F0-9]+$"
-       ) then
-               local parts = util.split( val, ":" )
-
-               for i = 1,6 do
-                       parts[i] = tonumber( parts[i], 16 )
-                       if parts[i] < 0 or parts[i] > 255 then
-                               return false
-                       end
-               end
-
-               return true
-       end
-
-       return false
+       return ip.checkmac(val) and true or false
 end
 
 function hostname(val)
 end
 
 function hostname(val)
index c8ec536..056fc67 100644 (file)
@@ -330,7 +330,7 @@ function init(cursor)
                        if i.family == "packet" then
                                _interfaces[name].flags   = i.flags
                                _interfaces[name].stats   = i.data
                        if i.family == "packet" then
                                _interfaces[name].flags   = i.flags
                                _interfaces[name].stats   = i.data
-                               _interfaces[name].macaddr = i.addr
+                               _interfaces[name].macaddr = ipc.checkmac(i.addr)
                        elseif i.family == "inet" then
                                _interfaces[name].ipaddrs[#_interfaces[name].ipaddrs+1] = ipc.IPv4(i.addr, i.netmask)
                        elseif i.family == "inet6" then
                        elseif i.family == "inet" then
                                _interfaces[name].ipaddrs[#_interfaces[name].ipaddrs+1] = ipc.IPv4(i.addr, i.netmask)
                        elseif i.family == "inet6" then
@@ -1233,8 +1233,7 @@ function interface.name(self)
 end
 
 function interface.mac(self)
 end
 
 function interface.mac(self)
-       local mac = self:_ubus("macaddr")
-       return mac and mac:upper()
+       return ipc.checkmac(self:_ubus("macaddr"))
 end
 
 function interface.ipaddrs(self)
 end
 
 function interface.ipaddrs(self)
index b00feda..12b20e4 100644 (file)
@@ -138,20 +138,21 @@ local function _nethints(what, callback)
 
        luci.ip.neighbors(nil, function(neigh)
                if neigh.mac and neigh.family == 4 then
 
        luci.ip.neighbors(nil, function(neigh)
                if neigh.mac and neigh.family == 4 then
-                       _add(what, neigh.mac:upper(), neigh.dest:string(), nil, nil)
+                       _add(what, neigh.mac:string(), neigh.dest:string(), nil, nil)
                elseif neigh.mac and neigh.family == 6 then
                elseif neigh.mac and neigh.family == 6 then
-                       _add(what, neigh.mac:upper(), nil, neigh.dest:string(), nil)
+                       _add(what, neigh.mac:string(), nil, neigh.dest:string(), nil)
                end
        end)
 
        if fs.access("/etc/ethers") then
                for e in io.lines("/etc/ethers") do
                end
        end)
 
        if fs.access("/etc/ethers") then
                for e in io.lines("/etc/ethers") do
-                       mac, name = e:match("^([a-fA-F0-9:]+)%s+(%S+)")
+                       mac, name = e:match("^([a-fA-F0-9:-]+)%s+(%S+)")
+                       mac = luci.ip.checkmac(mac)
                        if mac and name then
                        if mac and name then
-                               if luci.ip.IPv4(name) then
-                                       _add(what, mac:upper(), name, nil, nil)
+                               if luci.ip.checkip4(name) then
+                                       _add(what, mac, name, nil, nil)
                                else
                                else
-                                       _add(what, mac:upper(), nil, nil, name)
+                                       _add(what, mac, nil, nil, name)
                                end
                        end
                end
                                end
                        end
                end
@@ -162,8 +163,9 @@ local function _nethints(what, callback)
                        if s.leasefile and fs.access(s.leasefile) then
                                for e in io.lines(s.leasefile) do
                                        mac, ip, name = e:match("^%d+ (%S+) (%S+) (%S+)")
                        if s.leasefile and fs.access(s.leasefile) then
                                for e in io.lines(s.leasefile) do
                                        mac, ip, name = e:match("^%d+ (%S+) (%S+) (%S+)")
+                                       mac = luci.ip.checkmac(mac)
                                        if mac and ip then
                                        if mac and ip then
-                                               _add(what, mac:upper(), ip, nil, name ~= "*" and name)
+                                               _add(what, mac, ip, nil, name ~= "*" and name)
                                        end
                                end
                        end
                                        end
                                end
                        end
@@ -173,7 +175,10 @@ local function _nethints(what, callback)
        cur:foreach("dhcp", "host",
                function(s)
                        for mac in luci.util.imatch(s.mac) do
        cur:foreach("dhcp", "host",
                function(s)
                        for mac in luci.util.imatch(s.mac) do
-                               _add(what, mac:upper(), s.ip, nil, s.name)
+                               mac = luci.ip.checkmac(mac)
+                               if mac then
+                                       _add(what, mac, s.ip, nil, s.name)
+                               end
                        end
                end)
 
                        end
                end)
 
index 95ff46d..5012111 100644 (file)
@@ -4,6 +4,7 @@
 module("luci.tools.status", package.seeall)
 
 local uci = require "luci.model.uci".cursor()
 module("luci.tools.status", package.seeall)
 
 local uci = require "luci.model.uci".cursor()
+local ipc = require "luci.ip"
 
 local function dhcp_leases_common(family)
        local rv = { }
 
 local function dhcp_leases_common(family)
        local rv = { }
@@ -31,7 +32,7 @@ local function dhcp_leases_common(family)
                                        if family == 4 and not ip:match(":") then
                                                rv[#rv+1] = {
                                                        expires  = (expire ~= 0) and os.difftime(expire, os.time()),
                                        if family == 4 and not ip:match(":") then
                                                rv[#rv+1] = {
                                                        expires  = (expire ~= 0) and os.difftime(expire, os.time()),
-                                                       macaddr  = mac,
+                                                       macaddr  = ipc.checkmac(mac) or "00:00:00:00:00:00",
                                                        ipaddr   = ip,
                                                        hostname = (name ~= "*") and name
                                                }
                                                        ipaddr   = ip,
                                                        hostname = (name ~= "*") and name
                                                }
@@ -74,19 +75,9 @@ local function dhcp_leases_common(family)
                                                hostname = (name ~= "-") and name
                                        }
                                elseif ip and iaid == "ipv4" and family == 4 then
                                                hostname = (name ~= "-") and name
                                        }
                                elseif ip and iaid == "ipv4" and family == 4 then
-                                       local mac, mac1, mac2, mac3, mac4, mac5, mac6
-                                       if duid and type(duid) == "string" then
-                                                mac1, mac2, mac3, mac4, mac5, mac6 = duid:match("^(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)$")
-                                       end
-                                       if not (mac1 and mac2 and mac3 and mac4 and mac5 and mac6) then
-                                               mac = "FF:FF:FF:FF:FF:FF"
-                                       else
-                                               mac = mac1..":"..mac2..":"..mac3..":"..mac4..":"..mac5..":"..mac6
-                                       end
                                        rv[#rv+1] = {
                                                expires  = (expire >= 0) and os.difftime(expire, os.time()),
                                        rv[#rv+1] = {
                                                expires  = (expire >= 0) and os.difftime(expire, os.time()),
-                                               macaddr  = duid,
-                                               macaddr  = mac:lower(),
+                                               macaddr  = ipc.checkmac(duid:gsub("^(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)$", "%1:%2:%3:%4:%5:%6")) or "00:00:00:00:00:00",
                                                ipaddr   = ip,
                                                hostname = (name ~= "-") and name
                                        }
                                                ipaddr   = ip,
                                                hostname = (name ~= "-") and name
                                        }
index 2cb2108..33f6a67 100644 (file)
@@ -258,7 +258,6 @@ function iface_status(ifaces)
                                        type       = device:type(),
                                        ifname     = device:name(),
                                        macaddr    = device:mac(),
                                        type       = device:type(),
                                        ifname     = device:name(),
                                        macaddr    = device:mac(),
-                                       macaddr    = device:mac(),
                                        is_up      = device:is_up(),
                                        rx_bytes   = device:rx_bytes(),
                                        tx_bytes   = device:tx_bytes(),
                                        is_up      = device:is_up(),
                                        rx_bytes   = device:rx_bytes(),
                                        tx_bytes   = device:tx_bytes(),
index 2acda0b..66d9942 100644 (file)
@@ -2,6 +2,7 @@
 -- Licensed to the public under the Apache License 2.0.
 
 local ipc = require "luci.ip"
 -- Licensed to the public under the Apache License 2.0.
 
 local ipc = require "luci.ip"
+local sys = require "luci.sys"
 local o
 require "luci.util"
 
 local o
 require "luci.util"
 
@@ -311,10 +312,10 @@ end
 
 hostid = s:option(Value, "hostid", translate("<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Suffix (hex)"))
 
 
 hostid = s:option(Value, "hostid", translate("<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Suffix (hex)"))
 
-ipc.neighbors({ family = 4 }, function(n)
-       if n.mac and n.dest then
-               ip:value(n.dest:string())
-               mac:value(n.mac, "%s (%s)" %{ n.mac, n.dest:string() })
+sys.net.host_hints(function(m, v4, v6, name)
+       if m and v4 then
+               ip:value(v4)
+               mac:value(m, "%s (%s)" %{ m, name or v4 })
        end
 end)
 
        end
 end)
 
index fafacf3..46945af 100644 (file)
@@ -3,6 +3,7 @@
 -- Licensed to the public under the Apache License 2.0.
 
 local ipc = require "luci.ip"
 -- Licensed to the public under the Apache License 2.0.
 
 local ipc = require "luci.ip"
+local sys = require "luci.sys"
 
 m = Map("dhcp", translate("Hostnames"))
 
 
 m = Map("dhcp", translate("Hostnames"))
 
@@ -19,9 +20,11 @@ ip = s:option(Value, "ip", translate("IP address"))
 ip.datatype = "ipaddr"
 ip.rmempty  = true
 
 ip.datatype = "ipaddr"
 ip.rmempty  = true
 
-ipc.neighbors({ }, function(n)
-       if n.mac and n.dest and not n.dest:is6linklocal() then
-               ip:value(n.dest:string(), "%s (%s)" %{ n.dest:string(), n.mac })
+sys.net.host_hints(function(mac, v4, v6, name)
+       v6 = v6 and ipc.IPv6(v6)
+
+       if v4 or (v6 and not v6:is6linklocal()) then
+               ip:value(tostring(v4 or v6), "%s (%s)" %{ tostring(v4 or v6), name or mac })
        end
 end)
 
        end
 end)
 
index 5f2c074..f474c71 100644 (file)
@@ -53,7 +53,7 @@
                                <tr class="cbi-section-table-row cbi-rowstyle-<%=(style and 1 or 2)%>">
                                        <td class="cbi-value-field"><%=v.dest%></td>
                                        <td class="cbi-value-field"><%=v.mac%></td>
                                <tr class="cbi-section-table-row cbi-rowstyle-<%=(style and 1 or 2)%>">
                                        <td class="cbi-value-field"><%=v.dest%></td>
                                        <td class="cbi-value-field"><%=v.mac%></td>
-                                       <td class="cbi-value-field"><%=v.dev%></td>
+                                       <td class="cbi-value-field"><%=luci.tools.webadmin.iface_get_network(v.dev) or '(' .. v.dev .. ')'%></td>
                                </tr>
                                <%
                                                        style = not style
                                </tr>
                                <%
                                                        style = not style
index 9a1c1fe..bcc26cd 100644 (file)
@@ -3,7 +3,7 @@
 -- Licensed to the public under the Apache License 2.0.
 
 local uci = require "luci.model.uci".cursor()
 -- Licensed to the public under the Apache License 2.0.
 
 local uci = require "luci.model.uci".cursor()
-local ipc = require "luci.ip"
+local sys = require "luci.sys"
 local wa  = require "luci.tools.webadmin"
 local fs  = require "nixio.fs"
 
 local wa  = require "luci.tools.webadmin"
 local fs  = require "nixio.fs"
 
@@ -87,12 +87,11 @@ name = s2:option(Value, "name", translate("Hostname"))
 mac = s2:option(Value, "mac", translate("<abbr title=\"Media Access Control\">MAC</abbr>-Address"))
 ip = s2:option(Value, "ip", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Address"))
 
 mac = s2:option(Value, "mac", translate("<abbr title=\"Media Access Control\">MAC</abbr>-Address"))
 ip = s2:option(Value, "ip", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Address"))
 
-ipc.neighbors({ family = 4 }, function(n)
-       if n.mac and n.dest then
-               ip:value(n.dest:string())
-               mac:value(n.mac, "%s (%s)" %{ n.mac, n.dest:string() })
+sys.host_hints(function(m, v4, v6, name)
+       if m and v4 then
+               ip:value(v4)
+               mac:value(m, "%s (%s)" %{ m, name or v4 })
        end
 end)
 
 return m
        end
 end)
 
 return m
-