-- Init state session
local uci = require "luci.model.uci".cursor_state()
+local ipt = require "luci.sys.iptparser".IptParser()
local fs = require "nixio.fs"
local ip = require "luci.ip"
os.execute(cmd)
end
+function esc(str)
+ return utl.shellquote(str)
+end
+
function lock()
call("lock /var/run/luci_splash.lock")
function get_physdev(interface)
local dev
- dev = utl.trim(sys.exec(". /lib/functions/network.sh; network_get_device IFNAME '" .. interface .. "'; echo $IFNAME"))
+ dev = utl.trim(sys.exec(". /lib/functions/network.sh; network_get_device IFNAME %s; echo $IFNAME" % esc(interface)))
return dev
end
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 input = utl.split(sys.exec('/usr/sbin/tc filter show dev %s parent %s' %{ esc(device), esc(parent) }) or {})
local tbl = {}
local handle
for k, v in pairs(input) do
end
function mac_to_ip(mac)
+ local ipaddr = nil
ipc.neighbors({ family = 4 }, function(n)
if n.mac == mac and n.dest then
- return n.dest:string()
+ ipaddr = n.dest:string()
end
end)
+ return ipaddr
end
function mac_to_dev(mac)
+ local dev = nil
ipc.neighbors({ family = 4 }, function(n)
if n.mac == mac and n.dev then
- return n.dev
+ dev = n.dev
end
end)
+ return dev
end
function ip_to_mac(ip)
+ local mac = nil
ipc.neighbors({ family = 4 }, function(n)
if n.mac and n.dest and n.dest:equal(ip) then
- return n.mac
+ mac = n.mac
end
end)
+ return mac
end
function main(argv)
elseif whitelist_macs[mac] then
print("Removing %s from whitelist" % mac)
remove_whitelist(mac)
- whitelist_macs[mac] = nil
+ whitelist_macs[mac] = nil
elseif blacklist_macs[mac] then
print("Removing %s from blacklist" % mac)
remove_blacklist(mac)
print("\n luci-splash remove <MAC-or-IP>\n Remove given address from the lease-, black- or whitelist")
print("")
- os.exit(1)
+ os.exit(1)
end
end
off[r.table] = off[r.table] or { }
off[r.table][r.chain] = off[r.table][r.chain] or 0
- exec("iptables -t %q -D %q %d 2>/dev/null"
- %{ r.table, r.chain, r.index - off[r.table][r.chain] })
+ exec("iptables -t %s -D %s %d 2>/dev/null"
+ %{ esc(r.table), esc(r.chain), r.index - off[r.table][r.chain] })
off[r.table][r.chain] = off[r.table][r.chain] + 1
end
off[r.table] = off[r.table] or { }
off[r.table][r.chain] = off[r.table][r.chain] or 0
- exec("ip6tables -t %q -D %q %d 2>/dev/null"
- %{ r.table, r.chain, r.index - off[r.table][r.chain] })
+ exec("ip6tables -t %s -D %s %d 2>/dev/null"
+ %{ esc(r.table), esc(r.chain), r.index - off[r.table][r.chain] })
off[r.table][r.chain] = off[r.table][r.chain] + 1
end
end
local handle = get_filter_handle('ffff:', 'src', device, mac)
if handle then
- exec('tc filter del dev "%s" parent ffff: protocol ip prio 1 handle %s u32' % { device, handle })
+ exec('tc filter del dev %s parent ffff: protocol ip prio 1 handle %s u32' % { esc(device), esc(handle) })
else
print('Warning! Could not get a handle for %s parent :ffff on interface %s' % { mac, device })
end
local handle = get_filter_handle('1:', 'dest', device, mac)
if handle then
- exec('tc filter del dev "%s" parent 1:0 protocol ip prio 1 handle %s u32' % { device, handle })
+ exec('tc filter del dev %s parent 1:0 protocol ip prio 1 handle %s u32' % { esc(device), esc(handle) })
else
print('Warning! Could not get a handle for %s parent 1:0 on interface %s' % { mac, device })
end
id = get_id(ipaddr)
end
- exec("iptables -t mangle -I luci_splash_mark_out -m mac --mac-source %q -j RETURN" % mac)
+ exec("iptables -t mangle -I luci_splash_mark_out -m mac --mac-source %s -j RETURN" % esc(mac))
-- Mark incoming packets to a splashed host
-- for ipv4 - by iptables and destination
if id and device then
- exec("iptables -t mangle -I luci_splash_mark_in -d %q -j MARK --set-mark 0x1%s -m comment --comment %s" % {ipaddr, id, mac:upper()})
+ exec("iptables -t mangle -I luci_splash_mark_in -d %s -j MARK --set-mark 0x1%s -m comment --comment %s" % { esc(ipaddr), esc(id), esc(mac:upper())})
end
--for ipv6: need to use the mac here
if has_ipv6 then
- exec("ip6tables -t mangle -I luci_splash_mark_out -m mac --mac-source %q -j MARK --set-mark 79" % mac)
+ exec("ip6tables -t mangle -I luci_splash_mark_out -m mac --mac-source %s -j MARK --set-mark 79" % esc(mac))
if id and device and tonumber(limit_down) then
- exec("tc filter add dev %s parent 1:0 protocol ipv6 prio 1 u32 match ether dst %s classid 1:%s" % {device, mac:lower(), id})
+ exec("tc filter add dev %s parent 1:0 protocol ipv6 prio 1 u32 match ether dst %s classid 1:%s" % { esc(device), esc(mac:lower()), esc(id) })
end
end
if device and tonumber(limit_up) > 0 then
- exec('tc filter add dev "%s" parent ffff: protocol all prio 2 u32 match ether src %s police rate %skbit mtu 6k burst 6k drop' % {device, mac, limit_up})
+ exec('tc filter add dev %s parent ffff: protocol all prio 2 u32 match ether src %s police rate %skbit mtu 6k burst 6k drop' % { esc(device), esc(mac), esc(limit_up) })
end
if id and device and tonumber(limit_down) > 0 then
- exec("tc class add dev %s parent 1: classid 1:0x%s htb rate %skbit" % { device, id, limit_down })
- exec("tc qdisc add dev %s parent 1:%s sfq perturb 10" % { device, id })
+ exec("tc class add dev %s parent 1: classid 1:0x%s htb rate %skbit" % { esc(device), esc(id), esc(limit_down) })
+ exec("tc qdisc add dev %s parent 1:%s sfq perturb 10" % { esc(device), esc(id) })
end
- exec("iptables -t filter -I luci_splash_filter -m mac --mac-source %q -j RETURN" % mac)
- exec("iptables -t nat -I luci_splash_leases -m mac --mac-source %q -j RETURN" % mac)
+ exec("iptables -t filter -I luci_splash_filter -m mac --mac-source %s -j RETURN" % esc(mac))
+ exec("iptables -t nat -I luci_splash_leases -m mac --mac-source %s -j RETURN" % esc(mac))
if has_ipv6 then
- exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %q -j RETURN" % mac)
+ exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %s -j RETURN" % esc(mac))
end
end
if device and tonumber(limit_up) > 0 then
local handle = get_filter_handle('ffff:', 'src', device, mac)
if handle then
- exec('tc filter del dev "%s" parent ffff: protocol all prio 2 handle %s u32 police rate %skbit mtu 6k burst 6k drop' % {device, handle, limit_up})
+ exec('tc filter del dev %s parent ffff: protocol all prio 2 handle %s u32 police rate %skbit mtu 6k burst 6k drop' % { esc(device), esc(handle), esc(limit_up) })
else
print('Warning! Could not get a handle for %s parent :ffff on interface %s' % { mac, device })
end
end
-- remove clients class
if device and id then
- exec('tc class del dev "%s" classid 1:%s' % {device, id})
- exec('tc filter del dev "%s" parent 1:0 prio 1' % device) -- ipv6 rule
- --exec('tc qdisc del dev "%s" parent 1:%s sfq perturb 10' % { device, id })
+ exec('tc class del dev %s classid 1:%s' % { esc(device), esc(id) })
+ exec('tc filter del dev %s parent 1:0 prio 1' % esc(device)) -- ipv6 rule
+ --exec('tc qdisc del dev %s parent 1:%s sfq perturb 10' % { esc(device), esc(id) })
end
end
-- Add whitelist rules
function add_whitelist_rule(mac)
- exec("iptables -t filter -I luci_splash_filter -m mac --mac-source %q -j RETURN" % mac)
- exec("iptables -t nat -I luci_splash_leases -m mac --mac-source %q -j RETURN" % mac)
+ exec("iptables -t filter -I luci_splash_filter -m mac --mac-source %s -j RETURN" % esc(mac))
+ exec("iptables -t nat -I luci_splash_leases -m mac --mac-source %s -j RETURN" % esc(mac))
if has_ipv6 then
- exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %q -j RETURN" % mac)
+ exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %s -j RETURN" % esc(mac))
end
uci:foreach("luci_splash", "iface", function(s)
local device = get_physdev(s['.name'])
if device and device ~= "" then
- exec('tc filter add dev "%s" parent ffff: protocol ip prio 1 u32 match ether src %s police pass' % { device, mac })
- exec('tc filter add dev "%s" parent 1:0 protocol ip prio 1 u32 match ether dst %s classid 1:1' % { device, mac })
+ exec('tc filter add dev %s parent ffff: protocol ip prio 1 u32 match ether src %s police pass' % { esc(device), esc(mac) })
+ exec('tc filter add dev %s parent 1:0 protocol ip prio 1 u32 match ether dst %s classid 1:1' % { esc(device), esc(mac) })
end
end)
end
-- Add blacklist rules
function add_blacklist_rule(mac)
- exec("iptables -t filter -I luci_splash_filter -m mac --mac-source %q -j DROP" % mac)
+ exec("iptables -t filter -I luci_splash_filter -m mac --mac-source %s -j DROP" % esc(mac))
if has_ipv6 then
- exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %q -j DROP" % mac)
+ exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %s -j DROP" % esc(mac))
end
end
-- Current leases in state files
local leases = uci:get_all("luci_splash_leases")
-
+
-- Convert leasetime to seconds
local leasetime = tonumber(uci:get("luci_splash", "general", "leasetime")) * 3600
-
+
-- Clean state file
uci:load("luci_splash_leases")
uci:revert("luci_splash_leases")
-
+
local blackwhitelist = uci:get_all("luci_splash")
local whitelist_total = 0
local whitelist_online = 0
end
-- Rewrite state
- uci:section("luci_splash_leases", "lease", convert_mac_to_secname(v.mac), {
+ uci:section("luci_splash_leases", "lease", convert_mac_to_secname(v.mac), {
mac = v.mac,
ipaddr = v.ipaddr,
device = v.device,
end
end
end
-
+
-- Whitelist, Blacklist
for _, s in utl.spairs(blackwhitelist,
function(a,b) return blackwhitelist[a][".type"] > blackwhitelist[b][".type"] end
-- ToDo:
-- include a new field "leases_online" in stats to differ between active clients and leases:
- -- update_stats(leasecount, leases_online, whitelist_online, whitelist_total, blacklist_online, blacklist_total) later:
+ -- update_stats(leasecount, leases_online, whitelist_online, whitelist_total, blacklist_online, blacklist_total) later:
update_stats(leases_online, whitelist_online, whitelist_total, blacklist_online, blacklist_total)
uci:save("luci_splash_leases")