5 require("luci.model.uci")
8 local uci = luci.model.uci.cursor_state()
15 if cmd == "status" then
20 if iswhitelisted(arg) then
32 elseif cmd == "add" then
37 if not haslease(arg) then
40 print("already leased!")
44 elseif cmd == "remove" then
51 elseif cmd == "sync" then
55 print("Usage: " .. argv[0] .. " <status|add|remove|sync> [MAC]")
60 -- Add a lease to state and invoke add_rule
61 function add_lease(mac)
62 uci:section("luci_splash", "lease", nil, {
68 uci:save("luci_splash")
72 -- Remove a lease from state and invoke remove_rule
73 function remove_lease(mac)
77 uci:foreach("luci_splash", "lease",
79 if section.mac:lower() == mac then
80 table.insert(del, section[".name"])
84 for i,j in ipairs(del) do
86 uci:delete("luci_splash", j)
89 uci:save("luci_splash")
93 -- Add an iptables rule
94 function add_rule(mac)
95 return os.execute("iptables -t nat -I luci_splash_leases -m mac --mac-source '"..mac.."' -j RETURN")
99 -- Remove an iptables rule
100 function remove_rule(mac)
101 return os.execute("iptables -t nat -D luci_splash_leases -m mac --mac-source '"..mac.."' -j RETURN")
105 -- Check whether a MAC-Address is listed in the lease state list
106 function haslease(mac)
110 uci:foreach("luci_splash", "lease",
112 if section.mac:lower() == mac then
122 -- Check whether a MAC-Address is whitelisted
123 function iswhitelisted(mac)
126 uci:foreach("luci_splash", "whitelist",
128 if section.mac:lower() == mac then
138 -- Returns a list of MAC-Addresses for which a rule is existing
140 local cmd = "iptables -t nat -L luci_splash_leases | grep RETURN |"
141 cmd = cmd .. "egrep -io [0-9a-f]+:[0-9a-f]+:[0-9a-f]+:[0-9a-f]+:[0-9a-f]+:[0-9a-f]+"
142 return luci.util.split(luci.util.exec(cmd))
146 -- Synchronise leases, remove abandoned rules
149 local time = os.time()
151 -- Current leases in state files
152 local leases = uci:get_all("luci_splash")
154 -- Convert leasetime to seconds
155 local leasetime = tonumber(uci:get("luci_splash", "general", "leasetime")) * 3600
158 uci:load("luci_splash")
159 uci:revert("luci_splash")
163 for k, v in pairs(leases) do
164 if v[".type"] == "lease" then
165 if os.difftime(time, tonumber(v.start)) > leasetime then
170 uci:section("luci_splash", "lease", nil, {
174 written[v.mac:lower()] = 1
180 -- Delete rules without state
181 for i, r in ipairs(listrules()) do
182 if #r > 0 and not written[r:lower()] then
187 uci:save("luci_splash")