end
end
+function update_stats(leased, whitelisted, whitelisttotal, blacklisted, blacklisttotal)
+ local leases = uci:get_all("luci_splash_leases", "stats")
+ uci:delete("luci_splash_leases", "stats")
+ uci:section("luci_splash_leases", "stats", "stats", {
+ leases = leased or (leases and leases.leases) or 0,
+ whitelisttotal = whitelisttotal or (leased and leases.whitelisttotal) or 0,
+ whitelistonline = whitelisted or (leases and leases.whitelistonline) or 0,
+ blacklisttotal = blacklisttotal or (leases and leases.blacklisttotal) or 0,
+ blacklistonline = blacklisted or (leases and leases.blacklistonline) or 0,
+ })
+ uci:save("luci_splash_leases")
+end
+
function get_device_for_ip(ipaddr)
local dev
uci:foreach("network", "interface", function(s)
-function get_filter_handle(parent, direction, device)
+function get_filter_handle(parent, direction, device, mac)
local input = utl.split(sys.exec('/usr/sbin/tc filter show dev ' .. device .. ' parent ' .. parent) or {})
local tbl = {}
local handle
for k, v in pairs(input) do
handle = v:match('filter protocol ip pref %d+ u32 fh (%d*:%d*:%d*) order')
if handle then
- local mac1, mac2, mac3, mac4, mac5, mac6
+ local mac, mac1, mac2, mac3, mac4, mac5, mac6
if direction == 'src' then
mac1, mac2, mac3, mac4 = input[k+1]:match('match ([%a%d][%a%d])([%a%d][%a%d])([%a%d][%a%d])([%a%d][%a%d])/ffffffff')
mac5, mac6 = input[k+2]:match('match ([%a%d][%a%d])([%a%d][%a%d])0000/ffff0000')
end
end
end
- if tbl[mac:lower()] then
- handle = tbl[mac:lower()]
+ if tbl[mac] then
+ handle = tbl[mac]
end
return handle
end
end
end
+-- Get current arp cache
+function get_arpcache()
+ local arpcache = { }
+ for _, entry in ipairs(net.arptable()) do
+ arpcache[entry["HW address"]:lower()] = { entry["Device"]:lower(), entry["IP address"]:lower() }
+ end
+ return arpcache
+end
+
-- Get a list of known mac addresses
function get_known_macs(list)
local leased_macs = { }
if ipaddr then
local device = get_device_for_ip(ipaddr)
if not no_uci then
+ local leased = uci:get("luci_splash_leases", "stats", "leases")
+ if type(tonumber(leased)) == "number" then
+ update_stats(leased + 1, nil, nil, nil, nil)
+ end
+
uci:section("luci_splash_leases", "lease", convert_mac_to_secname(mac), {
mac = mac,
ipaddr = ipaddr,
function(s)
if s.mac:lower() == mac then
remove_lease_rule(mac, s.ipaddr, s.device, tonumber(s.limit_up), tonumber(s.limit_down))
+ local leased = uci:get("luci_splash_leases", "stats", "leases")
+ if type(tonumber(leased)) == "number" and tonumber(leased) > 0 then
+ update_stats(leased - 1, nil, nil, nil, nil)
+ end
return true
end
return false
uci:revert("luci_splash_leases")
-- For all leases
+ local leasecount = 0
for k, v in pairs(leases) do
if v[".type"] == "lease" then
if os.difftime(time, tonumber(v.start)) > leasetime then
-- Remove expired
remove_lease_rule(v.mac, v.ipaddr, v.device, tonumber(v.limit_up), tonumber(v.limit_down))
else
+ leasecount = leasecount + 1
-- Rewrite state
uci:section("luci_splash_leases", "lease", convert_mac_to_secname(v.mac), {
mac = v.mac,
end
end
end
-
- uci:save("luci_splash_leases")
-
+
-- Get the mac addresses of current leases
local macs = get_known_macs()
+ local arpcache = get_arpcache()
+
+ local blackwhitelist = uci:get_all("luci_splash")
+ local whitelist_total = 0
+ local whitelist_online = 0
+ local blacklist_total = 0
+ local blacklist_online = 0
+
+ -- Whitelist, Blacklist
+ for _, s in utl.spairs(blackwhitelist,
+ function(a,b) return blackwhitelist[a][".type"] > blackwhitelist[b][".type"] end
+ ) do
+ if (s[".type"] == "whitelist") then
+ whitelist_total = whitelist_total + 1
+ if s.mac then
+ local mac = s.mac:lower()
+ if arpcache[mac] then
+ whitelist_online = whitelist_online + 1
+ end
+ end
+ end
+ if (s[".type"] == "blacklist") then
+ blacklist_total = blacklist_total + 1
+ if s.mac then
+ local mac = s.mac:lower()
+ if arpcache[mac] then
+ blacklist_online = blacklist_online + 1
+ end
+ end
+ end
+ end
+
+ update_stats(leasecount, whitelist_online, whitelist_total, blacklist_online, blacklist_total)
+
+ uci:save("luci_splash_leases")
ipt:resync()
-- Show client info
function list()
- -- Get current arp cache
- local arpcache = { }
- for _, entry in ipairs(net.arptable()) do
- arpcache[entry["HW address"]:lower()] = { entry["Device"]:lower(), entry["IP address"]:lower() }
- end
-
+ local arpcache = get_arpcache()
-- Find traffic usage
local function traffic(lease)
local traffic_in = 0
-- Print listings
local leases = uci:get_all("luci_splash_leases")
+ local blackwhitelist = uci:get_all("luci_splash")
print(string.format(
"%-17s %-15s %-9s %-4s %-7s %20s",
end
-- Whitelist, Blacklist
- for _, s in utl.spairs(leases,
- function(a,b) return leases[a][".type"] > leases[b][".type"] end
+ for _, s in utl.spairs(blackwhitelist,
+ function(a,b) return blackwhitelist[a][".type"] > blackwhitelist[b][".type"] end
) do
if (s[".type"] == "whitelist" or s[".type"] == "blacklist") and s.mac then
local mac = s.mac:lower()