<%# Copyright 2009 Jo-Philipp Wich Licensed to the public under the Apache License 2.0. -%> <%- local utl = require "luci.util" local ipt = require "luci.sys.iptparser".IptParser() local uci = require "luci.model.uci".cursor_state() local wat = require "luci.tools.webadmin" local ipc = require "luci.ip" 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()] = { start = tonumber(s.start), limit = ( tonumber(s.start) + leasetime ), mac = s.mac:upper(), ipaddr = s.ipaddr, policy = "normal", packets = 0, bytes = 0, } end end) 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()] = { start = 0, limit = 0, mac = r.options[2]:upper(), policy = ( r.target == "RETURN" ) and "whitelist" or "blacklist", packets = 0, bytes = 0 } end end end for mac, client in pairs(clients) do client.bytes_in = 0 client.bytes_out = 0 client.packets_in = 0 client.packets_out = 0 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()}}) if rin and #rin > 0 then client.bytes_in = rin[1].bytes client.packets_in = rin[1].packets end if rout and #rout > 0 then client.bytes_out = rout[1].bytes client.packets_out = rout[1].packets end end end uci:foreach("luci_splash", "whitelist", function(s) if s.mac and clients[s.mac:lower()] then clients[s.mac:lower()].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") 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 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 local function showmac(mac) if not is_admin then mac = mac:gsub("(%S%S:%S%S):%S%S:%S%S:(%S%S:%S%S)", "%1:XX:XX:%2") end return mac end if luci.http.formvalue("status") == "1" then local rv = {} for _, c in utl.spairs(clients, function(a,b) if clients[a].policy == clients[b].policy then return (clients[a].start > clients[b].start) else return (clients[a].policy > clients[b].policy) end end) do if c.ip then rv[#rv+1] = { hostname = c.hostname or "?", ip = c.ip or "?", mac = showmac(c.mac) or "?", timeleft = (c.limit >= os.time()) and wat.date_format(c.limit-os.time()) or (c.policy ~= "normal") and "-" or "expired", trafficin = wat.byte_format(c.bytes_in) or "?", trafficout = wat.byte_format(c.bytes_out) or "?", policy = c.policy or "?" } end end luci.http.prepare_content("application/json") luci.http.write_json(rv) return end -%> <%+header%>

<%:Client-Splash%>

<%:Active Clients%>
<% if is_admin then %>
<% end %> <%- local count = 0 for _, c in utl.spairs(clients, function(a,b) if clients[a].policy == clients[b].policy then return (clients[a].start > clients[b].start) else return (clients[a].policy > clients[b].policy) end end) do if c.ip then count = count + 1 -%> <%- end end if count == 0 then -%> <%- end -%>
<%:Hostname%> <%:IP Address%> <%:MAC Address%> <%:Time remaining%> <%:Traffic in/out%> <%:Policy%>
<%=c.hostname or "" .. translate("unknown") .. ""%> <%=c.ip or "" .. translate("unknown") .. ""%> <%=showmac(c.mac)%> <%= (c.limit >= os.time()) and wat.date_format(c.limit-os.time()) or (c.policy ~= "normal") and "-" or "" .. translate("expired") .. "" %> <%=wat.byte_format(c.bytes_in)%> / <%=wat.byte_format(c.bytes_out)%> <% if is_admin then %> <% else %> <%=c.policy%> <% end %>

<%:No clients connected%>
<% if is_admin then %>
<% end %>
<%+footer%>