5 require("luci.model.uci")
8 luci.model.uci.set_savedir(luci.model.uci.savedir_state)
9 local uci = luci.model.uci
16 if cmd == "status" then
21 if iswhitelisted(arg) then
33 elseif cmd == "add" then
38 if not haslease(arg) then
41 print("already leased!")
45 elseif cmd == "remove" then
52 elseif cmd == "sync" then
56 print("Usage: " .. argv[0] .. " <status|add|remove|sync> [MAC]")
61 -- Add a lease to state and invoke add_rule
62 function add_lease(mac)
63 uci.section("luci_splash", "lease", nil, {
73 -- Remove a lease from state and invoke remove_rule
74 function remove_lease(mac)
78 uci.foreach("luci_splash", "lease",
80 if section.mac:lower() == mac then
81 table.insert(del, section[".name"])
85 for i,j in ipairs(del) do
87 uci.delete("luci_splash", j)
94 -- Add an iptables rule
95 function add_rule(mac)
96 return os.execute("iptables -t nat -I luci_splash_leases -m mac --mac-source '"..mac.."' -j RETURN")
100 -- Remove an iptables rule
101 function remove_rule(mac)
102 return os.execute("iptables -t nat -D luci_splash_leases -m mac --mac-source '"..mac.."' -j RETURN")
106 -- Check whether a MAC-Address is listed in the lease state list
107 function haslease(mac)
111 uci.foreach("luci_splash", "lease",
113 if section.mac:lower() == mac then
123 -- Check whether a MAC-Address is whitelisted
124 function iswhitelisted(mac)
127 uci.foreach("luci_splash", "whitelist",
129 if section.mac:lower() == mac then
139 -- Returns a list of MAC-Addresses for which a rule is existing
141 local cmd = "iptables -t nat -L luci_splash_leases | grep RETURN |"
142 cmd = cmd .. "egrep -io [0-9a-f]+:[0-9a-f]+:[0-9a-f]+:[0-9a-f]+:[0-9a-f]+:[0-9a-f]+"
143 return luci.util.split(luci.sys.exec(cmd))
147 -- Synchronise leases, remove abandoned rules
150 local time = os.time()
152 -- Current leases in state files
153 local leases = uci.get_all("luci_splash")
155 -- Convert leasetime to seconds
156 local leasetime = tonumber(uci.get("luci_splash", "general", "leasetime")) * 3600
159 uci.load("luci_splash")
160 uci.revert("luci_splash")
164 for k, v in pairs(leases) do
165 if v[".type"] == "lease" then
166 if os.difftime(time, tonumber(v.start)) > leasetime then
171 uci.section("luci_splash", "lease", nil, {
175 written[v.mac:lower()] = 1
181 -- Delete rules without state
182 for i, r in ipairs(listrules()) do
183 if #r > 0 and not written[r:lower()] then
188 uci.save("luci_splash")