luci-base: luci.tools.status: add host_hints to DHCPv6 leases
authorJo-Philipp Wich <jo@mein.io>
Thu, 28 Jun 2018 07:32:16 +0000 (09:32 +0200)
committerJo-Philipp Wich <jo@mein.io>
Thu, 28 Jun 2018 07:42:17 +0000 (09:42 +0200)
Attempt to derive a MAC from the DHCPv6 lease DUID and use it to look up
a host hint. If a hint is found, add it to the lease information.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
modules/luci-base/luasrc/tools/status.lua

index 0059ccceb03100ef567f61bc989574c72a1f9c06..635995310f640b758fa5d5afd79a0647c66c50ec 100644 (file)
@@ -6,9 +6,25 @@ module("luci.tools.status", package.seeall)
 local uci = require "luci.model.uci".cursor()
 local ipc = require "luci.ip"
 
+local function duid_to_mac(duid)
+       local b1, b2, b3, b4, b5, b6
+
+       -- DUID-LLT / Ethernet
+       if type(duid) == "string" and #duid == 28 then
+               b1, b2, b3, b4, b5, b6 = duid:match("^00010001(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)%x%x%x%x%x%x%x%x$")
+
+       -- DUID-LL / Ethernet
+       elseif type(duid) == "string" and #duid == 20 then
+               b1, b2, b3, b4, b5, b6 = duid:match("^00030001(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)$")
+       end
+
+       return b1 and ipc.checkmac(table.concat({ b1, b2, b3, b4, b5, b6 }, ":"))
+end
+
 local function dhcp_leases_common(family)
        local rv = { }
        local nfs = require "nixio.fs"
+       local sys = require "luci.sys"
        local leasefile = "/tmp/dhcp.leases"
 
        uci:foreach("dhcp", "dnsmasq",
@@ -87,6 +103,22 @@ local function dhcp_leases_common(family)
                fd:close()
        end
 
+       if family == 6 then
+               local _, lease
+               local hosts = sys.net.host_hints()
+               for _, lease in ipairs(rv) do
+                       local mac = duid_to_mac(lease.duid)
+                       local host = mac and hosts[mac]
+                       if host then
+                               if not lease.name then
+                                       lease.host_hint = host.name or host.ipv4 or host.ipv6
+                               elseif host.name and lease.hostname ~= host.name then
+                                       lease.host_hint = host.name
+                               end
+                       end
+               end
+       end
+
        return rv
 end