diff options
Diffstat (limited to 'applications/luci-splash')
18 files changed, 0 insertions, 1996 deletions
diff --git a/applications/luci-splash/Makefile b/applications/luci-splash/Makefile deleted file mode 100644 index 6e625c0e57..0000000000 --- a/applications/luci-splash/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -PO = splash - -include ../../build/config.mk -include ../../build/module.mk diff --git a/applications/luci-splash/README b/applications/luci-splash/README deleted file mode 100644 index 5a7af14c24..0000000000 --- a/applications/luci-splash/README +++ /dev/null @@ -1,5 +0,0 @@ - -* IPv6 support is only partial: - - will only work when used together with IPv4 (Dual stack) - - No bandwidth limiting - diff --git a/applications/luci-splash/htdocs/cgi-bin/splash/splash.sh b/applications/luci-splash/htdocs/cgi-bin/splash/splash.sh deleted file mode 100755 index 76f6d4d3e4..0000000000 --- a/applications/luci-splash/htdocs/cgi-bin/splash/splash.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/sh - -$(uci -q get luci_splash.general.redirect_url) || { - set -x - touch /var/state/luci_splash_locations - touch /etc/config/luci_splash_locations - MAC=$(grep "$REMOTE_HOST" /proc/net/arp | awk '{print $4}') - uci -P /var/state set luci_splash_locations.${MAC//:/}=redirect - uci -P /var/state set luci_splash_locations.${MAC//:/}.location="http://${HTTP_HOST}${REQUEST_URI}" - set +x -} - -echo -en "Cache-Control: no-cache, max-age=0, no-store, must-revalidate\r\n" -echo -en "Pragma: no-cache\r\n" -echo -en "Expires: -1\r\n" -echo -en "Status: 307 Temporary Redirect\r\n" -echo -en "Location: http://$SERVER_ADDR/cgi-bin/luci/splash\r\n" -echo -en "\r\n" - -cat <<EOT -<?xml version="1.0" encoding="UTF-8"?> -<WISPAccessGatewayParam xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.wballiance.net/wispr_2_0.xsd"> - <Redirect> - <MessageType>100</MessageType> - <ResponseCode>0</ResponseCode> - <AccessProcedure>1.0</AccessProcedure> - <AccessLocation>12</AccessLocation> - <LocationName>$SERVER_ADDR</LocationName> - <LoginURL>http://$SERVER_ADDR/cgi-bin/luci/splash?wispr=1</LoginURL> - <AbortLoginURL>http://$SERVER_ADDR/</AbortLoginURL> - </Redirect> -</WISPAccessGatewayParam> -EOT - - diff --git a/applications/luci-splash/htdocs/luci/splash/index.html b/applications/luci-splash/htdocs/luci/splash/index.html deleted file mode 100644 index 486409a2ef..0000000000 --- a/applications/luci-splash/htdocs/luci/splash/index.html +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> -<meta http-equiv="refresh" content="0; URL=/cgi-bin/luci/splash" /> -</head> -<body style="background-color: black"> -<a style="color: white; text-decoration: none" href="/cgi-bin/luci/splash">LuCI - Lua Configuration Interface</a> -</body> -</html> diff --git a/applications/luci-splash/ipkg/postinst b/applications/luci-splash/ipkg/postinst deleted file mode 100755 index a87729e431..0000000000 --- a/applications/luci-splash/ipkg/postinst +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -[ -n "${IPKG_INSTROOT}" ] || { - /etc/init.d/luci_splash enabled || /etc/init.d/luci_splash enable - exit 0 -} diff --git a/applications/luci-splash/luasrc/controller/splash/splash.lua b/applications/luci-splash/luasrc/controller/splash/splash.lua deleted file mode 100644 index 97d0400822..0000000000 --- a/applications/luci-splash/luasrc/controller/splash/splash.lua +++ /dev/null @@ -1,151 +0,0 @@ -module("luci.controller.splash.splash", package.seeall) - -local uci = luci.model.uci.cursor() -local util = require "luci.util" - -function index() - entry({"admin", "services", "splash"}, cbi("splash/splash"), _("Client-Splash"), 90) - entry({"admin", "services", "splash", "splashtext" }, form("splash/splashtext"), _("Splashtext"), 10) - - local e - - e = node("splash") - e.target = call("action_dispatch") - - node("splash", "activate").target = call("action_activate") - node("splash", "splash").target = template("splash_splash/splash") - node("splash", "blocked").target = template("splash/blocked") - - entry({"admin", "status", "splash"}, call("action_status_admin"), _("Client-Splash")) - - local page = node("splash", "publicstatus") - page.target = call("action_status_public") - page.leaf = true -end - -function action_dispatch() - local uci = luci.model.uci.cursor_state() - local mac = luci.sys.net.ip4mac(luci.http.getenv("REMOTE_ADDR")) or "" - local access = false - - uci:foreach("luci_splash", "lease", function(s) - if s.mac and s.mac:lower() == mac then access = true end - end) - uci:foreach("luci_splash", "whitelist", function(s) - if s.mac and s.mac:lower() == mac then access = true end - end) - - if #mac > 0 and access then - luci.http.redirect(luci.dispatcher.build_url()) - else - luci.http.redirect(luci.dispatcher.build_url("splash", "splash")) - end -end - -function blacklist() - leased_macs = { } - uci:foreach("luci_splash", "blacklist", - function(s) leased_macs[s.mac:lower()] = true - end) - return leased_macs -end - -function action_activate() - local ip = luci.http.getenv("REMOTE_ADDR") or "127.0.0.1" - local mac = luci.sys.net.ip4mac(ip:match("^[\[::ffff:]*(%d+.%d+%.%d+%.%d+)\]*$")) - local uci_state = require "luci.model.uci".cursor_state() - local blacklisted = false - if mac and luci.http.formvalue("accept") then - uci:foreach("luci_splash", "blacklist", - function(s) if s.mac:lower() == mac or s.mac == mac then blacklisted = true end - end) - if blacklisted then - luci.http.redirect(luci.dispatcher.build_url("splash" ,"blocked")) - else - local redirect_url = uci:get("luci_splash", "general", "redirect_url") - if not redirect_url then - redirect_url = uci_state:get("luci_splash_locations", mac:gsub(':', ''):lower(), "location") - end - if not redirect_url then - redirect_url = luci.model.uci.cursor():get("freifunk", "community", "homepage") or 'http://www.freifunk.net' - end - remove_redirect(mac:gsub(':', ''):lower()) - os.execute("luci-splash lease "..mac.." >/dev/null 2>&1") - luci.http.redirect(redirect_url) - end - else - luci.http.redirect(luci.dispatcher.build_url()) - end -end - -function action_status_admin() - local uci = luci.model.uci.cursor_state() - local macs = luci.http.formvaluetable("save") - - local changes = { - whitelist = { }, - blacklist = { }, - lease = { }, - remove = { } - } - - for key, _ in pairs(macs) do - local policy = luci.http.formvalue("policy.%s" % key) - local mac = luci.http.protocol.urldecode(key) - - if policy == "whitelist" or policy == "blacklist" then - changes[policy][#changes[policy]+1] = mac - elseif policy == "normal" then - changes["lease"][#changes["lease"]+1] = mac - elseif policy == "kicked" then - changes["remove"][#changes["remove"]+1] = mac - end - end - - if #changes.whitelist > 0 then - os.execute("luci-splash whitelist %s >/dev/null" - % table.concat(changes.whitelist)) - end - - if #changes.blacklist > 0 then - os.execute("luci-splash blacklist %s >/dev/null" - % table.concat(changes.blacklist)) - end - - if #changes.lease > 0 then - os.execute("luci-splash lease %s >/dev/null" - % table.concat(changes.lease)) - end - - if #changes.remove > 0 then - os.execute("luci-splash remove %s >/dev/null" - % table.concat(changes.remove)) - end - - luci.template.render("admin_status/splash", { is_admin = true }) -end - -function action_status_public() - luci.template.render("admin_status/splash", { is_admin = false }) -end - -function remove_redirect(mac) - local mac = mac:lower() - mac = mac:gsub(":", "") - local uci = require "luci.model.uci".cursor_state() - local redirects = uci:get_all("luci_splash_locations") - --uci:load("luci_splash_locations") - uci:revert("luci_splash_locations") - -- For all redirects - for k, v in pairs(redirects) do - if v[".type"] == "redirect" then - if v[".name"] ~= mac then - -- Rewrite state - uci:section("luci_splash_locations", "redirect", v[".name"], { - location = v.location - }) - end - end - end - uci:save("luci_splash_redirects") -end diff --git a/applications/luci-splash/luasrc/model/cbi/splash/splash.lua b/applications/luci-splash/luasrc/model/cbi/splash/splash.lua deleted file mode 100644 index 206ef70531..0000000000 --- a/applications/luci-splash/luasrc/model/cbi/splash/splash.lua +++ /dev/null @@ -1,87 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 -]]-- - -require("luci.model.uci") - -m = Map("luci_splash", translate("Client-Splash"), translate("Client-Splash is a hotspot authentification system for wireless mesh networks.")) - -s = m:section(NamedSection, "general", "core", translate("General")) -s.addremove = false - -s:option(Value, "leasetime", translate("Clearance time"), translate("Clients that have accepted the splash are allowed to use the network for that many hours.")) -local redir = s:option(Value, "redirect_url", translate("Redirect target"), translate("Clients are redirected to this page after they have accepted the splash. If this is left empty they are redirected to the page they had requested.")) -redir.rmempty = true - -s:option(Value, "limit_up", translate("Upload limit"), translate("Clients upload speed is limited to this value (kbyte/s)")) -s:option(Value, "limit_down", translate("Download limit"), translate("Clients download speed is limited to this value (kbyte/s)")) - -s:option(DummyValue, "_tmp", "", - translate("Bandwidth limit for clients is only activated when both up- and download limit are set. " .. - "Use a value of 0 here to completely disable this limitation. Whitelisted clients are not limited.")) - -s = m:section(TypedSection, "iface", translate("Interfaces"), translate("Interfaces that are used for Splash.")) - -s.template = "cbi/tblsection" -s.addremove = true -s.anonymous = true - -local uci = luci.model.uci.cursor() - -zone = s:option(ListValue, "zone", translate("Firewall zone"), - translate("Splash rules are integrated in this firewall zone")) - -uci:foreach("firewall", "zone", - function (section) - zone:value(section.name) - end) - -iface = s:option(ListValue, "network", translate("Network"), - translate("Intercept client traffic on this Interface")) - -uci:foreach("network", "interface", - function (section) - if section[".name"] ~= "loopback" then - iface:value(section[".name"]) - end - end) - -uci:foreach("network", "alias", - function (section) - iface:value(section[".name"]) - end) - - -s = m:section(TypedSection, "whitelist", translate("Whitelist"), - translate("MAC addresses of whitelisted clients. These do not need to accept the splash and are not bandwidth limited.")) - -s.template = "cbi/tblsection" -s.addremove = true -s.anonymous = true -s:option(Value, "mac", translate ("MAC Address")) - - -s = m:section(TypedSection, "blacklist", translate("Blacklist"), - translate("MAC addresses in this list are blocked.")) - -s.template = "cbi/tblsection" -s.addremove = true -s.anonymous = true -s:option(Value, "mac", translate ("MAC Address")) - -s = m:section(TypedSection, "subnet", translate("Allowed hosts/subnets"), - translate("Destination hosts and networks that are excluded from splashing, i.e. they are always allowed.")) - -s.template = "cbi/tblsection" -s.addremove = true -s.anonymous = true -s:option(Value, "ipaddr", translate("IP Address")) -s:option(Value, "netmask", translate("Netmask"), translate("optional when using host addresses")).rmempty = true - -return m diff --git a/applications/luci-splash/luasrc/model/cbi/splash/splashtext.lua b/applications/luci-splash/luasrc/model/cbi/splash/splashtext.lua deleted file mode 100644 index 00c5aba947..0000000000 --- a/applications/luci-splash/luasrc/model/cbi/splash/splashtext.lua +++ /dev/null @@ -1,66 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface - -Copyright 2008 Steven Barth <steven@midlink.org> -Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net> -Copyright 2010 Manuel Munz <freifunk@somakoma.de> - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 -]]-- - -local fs = require "nixio.fs" - -local splashtextfile = "/usr/lib/luci-splash/splashtext.html" -local splashtextinclude = "/usr/lib/luci-splash/splashtextinclude.html" - - -f = SimpleForm("splashtext", translate("Edit the complete splash text"), - translate("You can enter your own text that is displayed to clients here.<br />" .. - "It is possible to use the following markers: " .. - "###COMMUNITY###, ###COMMUNITY_URL###, ###CONTACTURL###, ###LEASETIME###, ###LIMIT### and ###ACCEPT###.")) - -t = f:field(TextValue, "text") -t.rmempty = true -t.rows = 30 -function t.cfgvalue() - return fs.readfile(splashtextfile) or "" -end - -function f.handle(self, state, data) - if state == FORM_VALID then - if data.text then - fs.writefile(splashtextfile, data.text:gsub("\r\n", "\n")) - else - fs.unlink(splashtextfile) - end - end - return true -end - -g = SimpleForm("splashtextinclude", translate("Include your own text in the default splash"), - translate("As an alternative to editing the complete splash text you can also just include some custom text in the default splash page by entering it here.")) - -t = g:field(TextValue, "text") -t.rmempty = true -t.rows = 30 -function t.cfgvalue() - return fs.readfile(splashtextinclude) or "" -end - -function g.handle(self, state, data) - if state == FORM_VALID then - if data.text then - fs.writefile(splashtextinclude, data.text:gsub("\r\n", "\n")) - else - fs.unlink(splashtextinclude) - end - end - return true -end - - -return f, g diff --git a/applications/luci-splash/luasrc/view/admin_status/splash.htm b/applications/luci-splash/luasrc/view/admin_status/splash.htm deleted file mode 100644 index 61b32bab9e..0000000000 --- a/applications/luci-splash/luasrc/view/admin_status/splash.htm +++ /dev/null @@ -1,294 +0,0 @@ -<%# -LuCI - Lua Configuration Interface -Copyright 2009 Jo-Philipp Wich <xm@leipzig.freifunk.net> - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -$Id$ - --%> - -<%- - -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 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, a in ipairs(luci.sys.net.arptable()) do - local c = clients[a["HW address"]:lower()] - if c and not c.ip then - c.ip = a["IP address"] - 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%> - -<script type="text/javascript" src="<%=resource%>/cbi.js"></script> -<script type="text/javascript">//<![CDATA[ - - XHR.poll(10 , '<%=REQUEST_URI%>', { status: 1 }, - function(x, info) - { - var tbody = document.getElementById('splash_table'); - if (tbody) - { - var s = ''; - if (info.length == undefined) { - s += '<tr class="cbi-section-table-row"><td colspan="7" class="cbi-section-table-cell"><br /><em><%:No clients connected%></em><br /></td></tr>' - }; - for (var idx = 0; idx < info.length; idx++) - { - var splash = info[idx]; - s += String.format( - '<tr class="cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+'">' + - '<td class="cbi-section-table-cell">%s</td>' + - '<td class="cbi-section-table-cell">%s</td>' + - '<td class="cbi-section-table-cell">%s</td>' + - '<td class="cbi-section-table-cell">%s</td>' + - '<td class="cbi-section-table-cell">%s/%s</td>' + - '<td class="cbi-section-table-cell">', - splash.hostname, splash.ip, splash.mac, splash.timeleft, splash.trafficin, splash.trafficout); - - <% if is_admin then %> - s += String.format('<select name="policy.%s" style="width:200px">', splash.mac.toLowerCase()); - if (splash.policy == 'whitelist') { - s += '<option value="whitelist" selected="selected"><%:whitelisted%></option>' - } else { - s += '<option value="whitelist"><%:whitelisted%></option>' - }; - if (splash.policy == 'normal') { - s += '<option value="normal" selected="selected"><%:splashed%></option>'; - s += '<option value="kicked"><%:temporarily blocked%></option>' - } else { - s += '<option value="normal"><%:splashed%></option>' - }; - if (splash.policy == 'blacklist') { - s+= '<option value="blacklist" selected="selected"><%:blacklisted%></option>' - } else { - s += '<option value="blacklist"><%:blacklisted%></option>' - }; - s += String.format( - '</select>' + - '<input type="submit" class="cbi-button cbi-button-save" name="save.%s" value="<%:Save%>" />', - splash.mac.toLowerCase()); - <% else %> - s += String.format('%s', splash.policy); - <% end %> - s += '</td></tr>' - } - tbody.innerHTML = s; - } - } - ); -//]]></script> - - -<div id="cbi-splash-leases" class="cbi-map"> - <h2><a id="content" name="content"><%:Client-Splash%></a></h2> - <fieldset id="cbi-table-table" class="cbi-section"> - <legend><%:Active Clients%></legend> - <div class="cbi-section-node"> - <% if is_admin then %><form action="<%=REQUEST_URI%>" method="post"><% end %> - <table class="cbi-section-table"> - <thead> - <tr class="cbi-section-table-titles"> - <th class="cbi-section-table-cell"><%:Hostname%></th> - <th class="cbi-section-table-cell"><%:IP Address%></th> - <th class="cbi-section-table-cell"><%:MAC Address%></th> - <th class="cbi-section-table-cell"><%:Time remaining%></th> - <th class="cbi-section-table-cell"><%:Traffic in/out%></th> - <th class="cbi-section-table-cell"><%:Policy%></th> - </tr> - </thead> - <tbody id="splash_table"> - - <%- - 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 - -%> - <tr class="cbi-section-table-row cbi-rowstyle-<%=2-(count%2)%>"> - <td class="cbi-section-table-cell"><%=c.hostname or "<em>" .. translate("unknown") .. "</em>"%></td> - <td class="cbi-section-table-cell"><%=c.ip or "<em>" .. translate("unknown") .. "</em>"%></td> - <td class="cbi-section-table-cell"><%=showmac(c.mac)%></td> - <td class="cbi-section-table-cell"><%= - (c.limit >= os.time()) and wat.date_format(c.limit-os.time()) or - (c.policy ~= "normal") and "-" or "<em>" .. translate("expired") .. "</em>" - %></td> - <td class="cbi-section-table-cell"><%=wat.byte_format(c.bytes_in)%> / <%=wat.byte_format(c.bytes_out)%></td> - <td class="cbi-section-table-cell"> - <% if is_admin then %> - <select name="policy.<%=c.mac:lower()%>" style="width:200px"> - <option value="whitelist"<%=c.policy=="whitelist" and ' selected="selected"'%>><%:whitelisted%></option> - <option value="normal"<%=c.policy=="normal" and not c.kicked and ' selected="selected"'%>><%:splashed%></option> - <option value="blacklist"<%=c.policy=="blacklist" and ' selected="selected"'%>><%:blacklisted%></option> - <% if c.policy == "normal" then -%> - <option value="kicked"><%:temporarily blocked%></option> - <%- end %> - </select> - <input type="submit" class="cbi-button cbi-button-save" name="save.<%=c.mac:lower()%>" value="<%:Save%>" /> - <% else %> - <%=c.policy%> - <% end %> - </td> - </tr> - <%- - end - end - if count == 0 then - -%> - <tr class="cbi-section-table-row"> - <td colspan="7" class="cbi-section-table-cell"> - <br /><em><%:No clients connected%></em><br /> - </td> - </tr> - <%- end -%> - </tbody> - </table> - <% if is_admin then %></form><% end %> - </div> - </fieldset> -</div> - -<%+footer%> diff --git a/applications/luci-splash/luasrc/view/splash/blocked.htm b/applications/luci-splash/luasrc/view/splash/blocked.htm deleted file mode 100644 index de61ecf011..0000000000 --- a/applications/luci-splash/luasrc/view/splash/blocked.htm +++ /dev/null @@ -1,25 +0,0 @@ -<%# -LuCI - Lua Configuration Interface -Copyright 2011 Manuel Munz <freifunk at somakoma dot de> - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 --%> -<% -local contacturl = luci.dispatcher.build_url("freifunk", "contact") -%> - -<%+header%> - -<h2><a id="content" name="content"><%:Blocked%></a></h2> - -<p><%:Your access to this network has been blocked, most likely because you did something that our rules explicitly forbid.%></p> -<p><%:To ask for the reason why you have been blocked or ask for access again you can try to contact the owner of this access point:%> <a href="<%=contacturl%>"><%:Contact%></a></p> - -<%+footer%> - - - diff --git a/applications/luci-splash/luasrc/view/splash/splash.htm b/applications/luci-splash/luasrc/view/splash/splash.htm deleted file mode 100644 index 2ebee273b4..0000000000 --- a/applications/luci-splash/luasrc/view/splash/splash.htm +++ /dev/null @@ -1,139 +0,0 @@ -<%# -LuCI - Lua Configuration Interface -Copyright 2008 Steven Barth <steven@midlink.org> -Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net> -Copyright 2011 Manuel Munz <freifunk at somakoma dot de> - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 --%> -<% -local fs = require "luci.fs" -local has_custom_splash = fs.access("/usr/lib/luci-splash/splashtext.html") -local has_custom_splashinclude = fs.access("/usr/lib/luci-splash/splashtextinclude.html") - -function expand (e, R) - return (string.gsub(e, "###([A-Z_]+)###", R)) -end - -local community, homepage, leasetime, limit_up, limit_down - -local contacturl = luci.dispatcher.build_url("freifunk", "contact") - -local c = luci.model.uci.cursor():get_all("freifunk", "community") -if c and c.name then - name = luci.model.uci.cursor():get('profile_' .. c.name, 'profile', 'name') - if name then - community = name - else - community = c.name - end -else - community = "Freifunk" -end - -if c and c.homepage then - homepage = c.homepage -else - homepage = "http://freifunk.net" -end - -local s = luci.model.uci.cursor():get_all("luci_splash", "general") -if s then - leasetime = s.leasetime or "" - limit_up = s.limit_up or nil - limit_down = s.limit_down or nil -end - -local limit_text = "" -if limit_up and limit_down then - limit_text = "<p>" .. translate("Your bandwidth is limited to") .. " " .. limit_down .. "/" .. limit_up .. - " " .. translate("KB/s (Download/Upload). You may be able to remove this limit by actively contributing " .. - "to this project.") .. "</p>" -end - -local contact = translate('Get in %s with the operator of this access point.') -contact = contact % ('<a href="' .. contacturl .. '">' .. translatef('Contact') .. '</a>') - -local accepttext = translate('By accepting these rules you can use this network for %s hour(s). After this time you need to accept these rules again.') -accepttext = accepttext % leasetime - - -if has_custom_splash then - local R = { - COMMUNITY = community, - COMMUNITY_URL = homepage, - LEASETIME = leasetime, - ACCEPT = tostring(translate("Accept")), - LIMIT = limit_text, - CONTACTURL = contacturl - } - local splashtext = expand(fs.readfile("/usr/lib/luci-splash/splashtext.html"), R) - %> - <%=splashtext%> - -<% else %> - - <h2><a id="content" name="content"><%:Welcome%></a></h2> - - <p><%:You are now connected to the free wireless mesh network%> <a href="<%=homepage%>"><%=community%></a>. - <%:Please note that we are not an internet service provider but an experimental community network.%></p> - <p><%:Access to the internet might be possible nevertheless, because some activists of this project share their - private internet connections. These few connections are shared between all users. That means available bandwidth - is limited and because of this we ask you not to do any of the following:%></p> - <ul> - <li><%:use filesharing applications on this network%></li> - <li><%:waste bandwidth with unneccesary downloads or streams%></li> - <li><%:perform any kind of illegal activities%></li> - </ul> - <br /> - - <% if limit_up and limit_down then %> - <%=limit_text%> - <% end %> - - <p><%:If you use this network on a regular basis we ask for your support:%></p> - <ul> - <li><a href="<%=homepage%>"><%:Become an active member of this community and help by operating your own node%></a></li> - <li><%=contact%></li> - <li><%:Donate some money to help us keep this project alive.%></li> - <li><%:If you operate your own wifi equipment use channels different from ours.%></li> - </ul> - - <% - if has_custom_splashinclude then - local splashtextinclude = fs.readfile("/usr/lib/luci-splash/splashtextinclude.html") - %> - <%=splashtextinclude%> - <% end %> - - <h2><%:Usage Agreement%></h2> - <p> - <%:The open and free wireless network of volunteers ("Operators") provides the necessary equipment and Internet connections ("Infrastructure") at their own expense.%> - <%:These Terms of Use govern the use of the network by its participants' computer, PDA, or similar device ("Devices") within the network.%> - <%:Access to the network is not guaranteed. It can be interrupted at any time without notice for any reason, for certain devices, and/or may be blocked for certain users.%> - </p> - - <h3><%:Legally Prohibited Activities%></h3> - <p><%:The participant agrees to not perform any action and refrain from acts which may violate the law or infringe upon the rights of third parties.%></p> - - <h3><%:Legally Prohibited content%></h3> - <p><%:The participant agrees to not transfer content over the network which violates the law.%></p> - - <h3><%:Fair Use Policy%></h3> - <p><%:The participant agrees to not use the network in any way which will harm the infrastructure, the network itself, its operators or other participants.%></p> - - <h3><%:Safety%></h3> - <p><%:The network, like the Internet, is unencrypted and open. Each participant is responsible for the safety of their own connections and devices.%></p> - - <h3>Disclaimer</h3> - <p><%:The operator claims no liability for loss of data, unauthorized access/damage to devices, or financial losses that participants may suffer from the use of the network.%></p> - - <br /><p><b><%=accepttext%></b></p> -<% end %> - - - diff --git a/applications/luci-splash/luasrc/view/splash_splash/index.htm b/applications/luci-splash/luasrc/view/splash_splash/index.htm deleted file mode 100644 index ab754913d3..0000000000 --- a/applications/luci-splash/luasrc/view/splash_splash/index.htm +++ /dev/null @@ -1,16 +0,0 @@ -<%# -LuCI - Lua Configuration Interface -Copyright 2008 Steven Barth <steven@midlink.org> -Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net> - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -$Id$ - --%> -<%+header%> -<%+footer%>
\ No newline at end of file diff --git a/applications/luci-splash/luasrc/view/splash_splash/splash.htm b/applications/luci-splash/luasrc/view/splash_splash/splash.htm deleted file mode 100644 index 8554913cd8..0000000000 --- a/applications/luci-splash/luasrc/view/splash_splash/splash.htm +++ /dev/null @@ -1,25 +0,0 @@ -<%# -LuCI - Lua Configuration Interface -Copyright 2008 Steven Barth <steven@midlink.org> -Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net> - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -$Id$ - --%> -<%+header%> -<%+splash/splash%> - -<form method="get" action="<%=controller%>/splash/activate"> - <p> - <input type="submit" value="<%:Decline%>" /> - <input type="submit" name="accept" value="<%:Accept%>" /> - </p> -</form> - -<%+footer%> diff --git a/applications/luci-splash/root/etc/config/luci_splash b/applications/luci-splash/root/etc/config/luci_splash deleted file mode 100644 index c4cfef5dd9..0000000000 --- a/applications/luci-splash/root/etc/config/luci_splash +++ /dev/null @@ -1,2 +0,0 @@ -config core general - option leasetime 1
\ No newline at end of file diff --git a/applications/luci-splash/root/etc/config/luci_splash_leases b/applications/luci-splash/root/etc/config/luci_splash_leases deleted file mode 100644 index 6afdd90ede..0000000000 --- a/applications/luci-splash/root/etc/config/luci_splash_leases +++ /dev/null @@ -1 +0,0 @@ -# This file should always stay empty and is just needed to be able to use this config in /var/state! diff --git a/applications/luci-splash/root/etc/hotplug.d/iface/25-splash b/applications/luci-splash/root/etc/hotplug.d/iface/25-splash deleted file mode 100644 index 045e908c72..0000000000 --- a/applications/luci-splash/root/etc/hotplug.d/iface/25-splash +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -[ "$ACTION" = ifup ] || exit 0 - -/etc/init.d/firewall enabled || exit 0 - -if [ -x /etc/init.d/luci_splash ]; then - restart_splash() { - local net="$1" - if [ "$INTERFACE" = "$net" ]; then - logger -t splash "Reloading splash firewall rules due to ifup of $INTERFACE ($DEVICE)" - /etc/init.d/luci_splash restart - fi - } - config_load luci_splash - config_foreach restart_splash iface -fi diff --git a/applications/luci-splash/root/etc/init.d/luci_splash b/applications/luci-splash/root/etc/init.d/luci_splash deleted file mode 100755 index feefabd81a..0000000000 --- a/applications/luci-splash/root/etc/init.d/luci_splash +++ /dev/null @@ -1,362 +0,0 @@ -#!/bin/sh /etc/rc.common - -START=70 -EXTRA_COMMANDS=clear_leases -LIMIT_DOWN=0 -LIMIT_DOWN_BURST=0 -LIMIT_UP=0 -TC=/usr/sbin/tc -IPT=/usr/sbin/iptables -IPT6=/usr/sbin/ip6tables - -IPT_REPLAY=/var/run/luci_splash.iptlog -LOCK=/var/run/luci_splash.lock -[ -x $IPT6 ] && [ -f /proc/net/ipv6_route ] && HAS_IPV6=1 - -silent() { - "$@" 2>/dev/null -} - -ipt_log() { - $IPT -I "$@" - echo $IPT -D "$@" >> $IPT_REPLAY -} - -ipt6_log() { - [ "$HAS_IPV6" = 1 ] || return - $IPT6 -I "$@" - echo $IPT6 -D "$@" >> $IPT_REPLAY -} - - -iface_add() { - local cfg="$1" - - config_get zone "$cfg" zone - [ -n "$zone" ] || return 0 - - config_get net "$cfg" network - [ -n "$net" ] || return 0 - - config_get ifname "$net" ifname - [ -n "$ifname" ] || return 0 - - config_get ipaddr "$net" ipaddr - [ -n "$ipaddr" ] || return 0 - - config_get netmask "$net" netmask - [ -n "$netmask" ] || return 0 - - config_get ip6addr "$net" ip6addr - - config_get type "$net" type - - parentiface="$(uci -q get network.${net}.ifname)" - - [ -n "$parentiface" ] && [ ! "$type" = "bridge" ] && { - parentiface=${parentiface#@} - config_get parentproto "$parentiface" proto - config_get parentipaddr "$parentiface" ipaddr - config_get parentnetmask "$parentiface" netmask - } - - eval "$(ipcalc.sh $ipaddr $netmask)" - - logger -s -p info -t splash "Add $NETWORK/$PREFIX ($ifname) to splashed networks." - - ### Add interface specific chain entry rules - ipt_log "prerouting_${zone}_rule" -i "${ifname%:*}" -s "$NETWORK/$PREFIX" -j luci_splash_prerouting -t nat - ipt_log "forwarding_${zone}_rule" -i "${ifname%:*}" -s "$NETWORK/$PREFIX" -j luci_splash_forwarding -t filter - - if [ "$HAS_IPV6" = 1 ] && [ -n "$ip6addr" ]; then - ipt6_log "forwarding_${zone}_rule" -i "${ifname%:*}" -s "$ip6addr" -j luci_splash_forwarding -t filter - fi - - ### Allow traffic to the same subnet - $IPT -t nat -I luci_splash_prerouting -d "$ipaddr/${netmask:-32}" -j RETURN - $IPT -t filter -I luci_splash_forwarding -d "$ipaddr/${netmask:-32}" -j RETURN - - ### Allow traffic to the mesh subnet - [ "$parentproto" = "static" -a -n "$parentipaddr" ] && { - $IPT -t nat -I luci_splash_prerouting -d "$parentipaddr/${parentnetmask:-32}" -j RETURN - $IPT -t filter -I luci_splash_forwarding -d "$parentipaddr/${parentnetmask:-32}" -j RETURN - } - - qos_iface_add "$ifname" "$NETWORK" "$PREFIX" -} - -iface_del() { - config_get zone "$1" zone - [ -n "$zone" ] || return 0 - - config_get net "$1" network - [ -n "$net" ] || return 0 - - config_get ifname "$net" ifname - [ -n "$ifname" ] || return 0 - - # Clear interface specific rules - [ -s $IPT_REPLAY ] && { - logger -s -p info -t splash "Remove $ifname from splashed networks." - grep -- "-i ${ifname%:*}" $IPT_REPLAY | while read ln; do silent $ln; done - sed -ie "/-i ${ifname%:*}/d" $IPT_REPLAY - } - - qos_iface_del "$ifname" -} - -mac_add() { - config_get mac "$1" mac - append MACS "$mac" -} - -whitelist_add() { - config_get mac "$1" mac - iface=$2 - $TC filter add dev "$iface" parent ffff: protocol ip prio 1 u32 match ether src $mac police pass - $TC filter add dev "$iface" parent 1:0 protocol ip prio 1 u32 match ether dst $mac classid 1:1 -} - - -subnet_add() { - local cfg="$1" - - config_get ipaddr "$cfg" ipaddr - config_get netmask "$cfg" netmask - - [ -n "$ipaddr" ] && { - $IPT -t nat -I luci_splash_prerouting -d "$ipaddr/${netmask:-32}" -j RETURN - $IPT -t filter -I luci_splash_forwarding -d "$ipaddr/${netmask:-32}" -j RETURN - } -} - -qos_iface_add() { - local iface="$1" - local network="$2" - local prefix="$3" - - # 77 -> download root qdisc - # ffff -> upload root qdisc - - silent $TC qdisc del dev "$iface" root handle 1: - silent $TC class del dev "$iface" parent 1: classid 1:ffff - silent $TC class del dev "$iface" parent 1: classid 1:1 - silent $TC filter del dev "$iface" parent ffff: protocol ip prio 1 u32 - silent $TC filter del dev "$iface" parent ffff: protocol ip prio 2 u32 - silent $TC filter del dev "$iface" parent ffff: protocol ip prio 3 u32 - - if [ "$LIMIT_UP" -gt 0 -a "$LIMIT_DOWN" -gt 0 ]; then - # Setup qdiscs - $TC qdisc add dev "$iface" root handle 1: htb default 1 - silent $TC qdisc add dev "$iface" ingress - - # Default class - all clients which are not otherwise handled are put in that class - # and share that bandwidth. - $TC class add dev "$iface" parent 1: classid 1:ffff htb rate ${LIMIT_DOWN}kbit - - # default class and class for whitelisted clients = unlimited - $TC class add dev "$iface" parent 1: classid 1:1 htb rate 100mbit - - # All traffic to the dhcp subnet is put into the limited class - $TC filter add dev "$iface" parent 1:0 protocol ip prio 3 u32 match ip dst $network/$prefix classid 1:ffff - $TC qdisc add dev "$iface" parent 1:ffff sfq perturb 10 - $TC filter add dev "$iface" parent ffff: protocol ip prio 3 u32 match ip src $network/$prefix police rate ${LIMIT_UP}kbit mtu 6k burst 6k drop - - # classify packets by their iptables MARK set in luci_splash_mark_in (mangle table) - # every client gets his own class and so his own bandwidth limit - $TC filter add dev "$iface" parent 1:0 protocol ip prio 2 fw - - config_foreach whitelist_add whitelist $iface - fi -} - -qos_iface_del() { - local iface="$1" - silent $TC qdisc del dev "$iface" root handle 77: -} - -boot() { - ### Setup splash-relay - uci get uhttpd.splash 2>/dev/null || { -uci batch <<EOF - set uhttpd.splash=uhttpd - set uhttpd.splash.home="/www/cgi-bin/splash/" - set uhttpd.splash.interpreter=".sh=/bin/ash" - set uhttpd.splash.listen_http="8082" - set uhttpd.splash.index_page="splash.sh" - set uhttpd.splash.error_page="/splash.sh" - set uhttpd.splash.http_keepalive='0' - commit uhttpd -EOF - } - - ### We are started by the firewall include - exit 0 -} - -start() { - lock $LOCK - logger -s -p info -t splash "Starting luci-splash" - include /lib/network - . /lib/functions/network.sh - scan_interfaces - config_load luci_splash - - ### Find QoS limits - config_get LIMIT_UP general limit_up - config_get LIMIT_DOWN general limit_down - config_get LIMIT_DOWN_BURST general limit_down_burst - - LIMIT_UP="$((8*${LIMIT_UP:-0}))" - LIMIT_DOWN="$((8*${LIMIT_DOWN:-0}))" - LIMIT_DOWN_BURST="${LIMIT_DOWN_BURST:+$((8*$LIMIT_DOWN_BURST))}" - LIMIT_DOWN_BURST="${LIMIT_DOWN_BURST:-$(($LIMIT_DOWN / 5 * 6))}" - - ### Load required modules - [ "$LIMIT_UP" -gt 0 -a "$LIMIT_DOWN" -gt 0 ] && { - silent insmod act_police - silent insmod cls_fw - silent insmod cls_u32 - silent insmod sch_htb - silent insmod sch_sfq - silent insmod sch_ingress - } - - ### Create subchains - $IPT -t nat -N luci_splash_prerouting - $IPT -t nat -N luci_splash_leases - $IPT -t filter -N luci_splash_forwarding - $IPT -t filter -N luci_splash_filter - - if [ "$HAS_IPV6" = 1 ]; then - $IPT6 -t filter -N luci_splash_forwarding - $IPT6 -t filter -N luci_splash_filter - fi - - ### Clear iptables replay log - [ -s $IPT_REPLAY ] && . $IPT_REPLAY - echo -n > $IPT_REPLAY - - ### Add interface independant prerouting rules - $IPT -t nat -A luci_splash_prerouting -j luci_splash_leases - $IPT -t nat -A luci_splash_leases -p udp --dport 53 -j REDIRECT --to-ports 53 - $IPT -t nat -A luci_splash_leases -p tcp --dport 80 -j REDIRECT --to-ports 8082 - - ### Add interface independant forwarding rules - $IPT -t filter -A luci_splash_forwarding -j luci_splash_filter - $IPT -t filter -A luci_splash_filter -p tcp -j REJECT --reject-with tcp-reset - $IPT -t filter -A luci_splash_filter -j REJECT --reject-with icmp-net-prohibited - - if [ "$HAS_IPV6" = 1 ]; then - $IPT6 -t filter -A luci_splash_forwarding -j luci_splash_filter - $IPT6 -t filter -A luci_splash_filter -p tcp -j REJECT --reject-with tcp-reset - $IPT6 -t filter -A luci_splash_filter -j REJECT --reject-with adm-prohibited - fi - - ### Add QoS chain - $IPT -t mangle -N luci_splash_mark_out - $IPT -t mangle -N luci_splash_mark_in - $IPT -t mangle -I PREROUTING -j luci_splash_mark_out - $IPT -t mangle -I POSTROUTING -j luci_splash_mark_in - - if [ "$HAS_IPV6" = 1 ]; then - $IPT6 -t mangle -N luci_splash_mark_out - $IPT6 -t mangle -N luci_splash_mark_in - $IPT6 -t mangle -I PREROUTING -j luci_splash_mark_out - $IPT6 -t mangle -I POSTROUTING -j luci_splash_mark_in - fi - - ### Build the main and portal rule - config_foreach iface_add iface - config_foreach subnet_add subnet - - ### Add the community homepage to the list of allowed destination subnets - hp=$(uci -q get freifunk.community.homepage) && { - chp=${hp#http*://} - chp=${chp%%/*} - $IPT -t nat -I luci_splash_prerouting -d "${chp}/32" -j RETURN - $IPT -t filter -I luci_splash_forwarding -d "${chp}/32" -j RETURN - } - - ### Find active mac addresses - MACS="" - - - config_foreach mac_add blacklist - config_foreach mac_add whitelist - - config_load luci_splash_leases - config_foreach mac_add lease - - ### Add crontab entry - test -f /etc/crontabs/root || touch /etc/crontabs/root - grep -q luci-splash /etc/crontabs/root || { - echo '*/5 * * * * /usr/sbin/luci-splash sync' >> /etc/crontabs/root - } - - lock -u $LOCK - - ### Populate iptables - [ -n "$MACS" ] && luci-splash add-rules $MACS -} - -stop() { - lock $LOCK - - include /lib/network - scan_interfaces - config_load luci_splash - - ### Clear interface rules - config_foreach iface_del iface - - silent $IPT -t mangle -D PREROUTING -j luci_splash_mark_out - silent $IPT -t mangle -D POSTROUTING -j luci_splash_mark_in - - if [ "$HAS_IPV6" = 1 ]; then - silent $IPT6 -t mangle -D PREROUTING -j luci_splash_mark_out - silent $IPT6 -t mangle -D POSTROUTING -j luci_splash_mark_in - fi - - ### Clear subchains - silent $IPT -t nat -F luci_splash_prerouting - silent $IPT -t nat -F luci_splash_leases - silent $IPT -t filter -F luci_splash_forwarding - silent $IPT -t filter -F luci_splash_filter - silent $IPT -t mangle -F luci_splash_mark_out - silent $IPT -t mangle -F luci_splash_mark_in - - if [ "$HAS_IPV6" = 1 ]; then - $IPT6 -t filter -F luci_splash_forwarding - $IPT6 -t filter -F luci_splash_filter - $IPT6 -t mangle -F luci_splash_mark_out - $IPT6 -t mangle -F luci_splash_mark_in - fi - - ### Delete subchains - silent $IPT -t nat -X luci_splash_prerouting - silent $IPT -t nat -X luci_splash_leases - silent $IPT -t filter -X luci_splash_forwarding - silent $IPT -t filter -X luci_splash_filter - silent $IPT -t mangle -X luci_splash_mark_out - silent $IPT -t mangle -X luci_splash_mark_in - if [ "$HAS_IPV6" = 1 ]; then - $IPT6 -t filter -X luci_splash_forwarding - $IPT6 -t filter -X luci_splash_filter - $IPT6 -t mangle -X luci_splash_mark_out - $IPT6 -t mangle -X luci_splash_mark_in - fi - sed -ie '/\/usr\/sbin\/luci-splash sync/d' /var/spool/cron/crontabs/root - - lock -u $LOCK -} - -clear_leases() { - ### Find active mac addresses - MACS="" - config_foreach mac_add lease - - ### Clear leases - [ -n "$MACS" ] && luci-splash remove $MACS -} - diff --git a/applications/luci-splash/root/usr/sbin/luci-splash b/applications/luci-splash/root/usr/sbin/luci-splash deleted file mode 100755 index 6b1e41edbd..0000000000 --- a/applications/luci-splash/root/usr/sbin/luci-splash +++ /dev/null @@ -1,751 +0,0 @@ -#!/usr/bin/lua - -utl = require "luci.util" -sys = require "luci.sys" - -require("luci.model.uci") -require("luci.sys.iptparser") - --- Init state session -local uci = luci.model.uci.cursor_state() -local ipt = luci.sys.iptparser.IptParser() -local net = sys.net -local fs = require "luci.fs" -local ip = require "luci.ip" - -local debug = false - -local has_ipv6 = fs.access("/proc/net/ipv6_route") and fs.access("/usr/sbin/ip6tables") - -function exec(cmd) - -- executes a cmd and gets its output - if debug then - local ret = sys.exec(cmd) - print('+ ' .. cmd) - if ret and ret ~= "" then - print(ret) - end - else - local ret = sys.exec(cmd .. " &> /dev/null") - end -end - -function call(cmd) - -- just calls a command - if debug then - print('+ ' .. cmd) - end - os.execute(cmd) -end - - -function lock() - call("lock /var/run/luci_splash.lock") -end - -function unlock() - call("lock -u /var/run/luci_splash.lock") -end - -function get_id(ip) - local o3, o4 = ip:match("[0-9]+%.[0-9]+%.([0-9]+)%.([0-9]+)") - if o3 and 04 then - return string.format("%02X%s", tonumber(o3), "") .. string.format("%02X%s", tonumber(o4), "") - else - return false - 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) - if s.ipaddr and s.netmask then - local network = ip.IPv4(s.ipaddr, s.netmask) - if network:contains(ip.IPv4(ipaddr)) then - -- this should be rewritten to luci functions if possible - dev = utl.trim(sys.exec(". /lib/functions/network.sh; network_get_device IFNAME '" .. s['.name'] .. "'; echo $IFNAME")) - end - end - end) - return dev -end - -function get_physdev(interface) - local dev - dev = utl.trim(sys.exec(". /lib/functions/network.sh; network_get_device IFNAME '" .. interface .. "'; echo $IFNAME")) - 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 tbl = {} - local handle - for k, v in pairs(input) do - handle = v:match('filter protocol ip pref %d+ u32 fh (%d*:%d*:%d*) order') or v:match('filter protocol all pref %d+ u32 fh (%d*:%d*:%d*) order') - if handle then - 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') - else - mac1, mac2 = input[k+1]:match('match 0000([%a%d][%a%d])([%a%d][%a%d])/0000ffff') - mac3, mac4, mac5, mac6 = input[k+2]:match('match ([%a%d][%a%d])([%a%d][%a%d])([%a%d][%a%d])([%a%d][%a%d])/ffffffff') - end - if mac1 and mac2 and mac3 and mac4 and mac5 and mac6 then - mac = "%s:%s:%s:%s:%s:%s" % { mac1, mac2, mac3, mac4, mac5, mac6 } - tbl[mac] = handle - end - end - end - if tbl[mac] then - handle = tbl[mac] - end - return handle -end - -function macvalid(mac) - if mac and mac:match( - "^[a-fA-F0-9][a-fA-F0-9]:[a-fA-F0-9][a-fA-F0-9]:" .. - "[a-fA-F0-9][a-fA-F0-9]:[a-fA-F0-9][a-fA-F0-9]:" .. - "[a-fA-F0-9][a-fA-F0-9]:[a-fA-F0-9][a-fA-F0-9]$" - ) then - return true - end - - return false -end - -function ipvalid(ipaddr) - if ipaddr then - return ip.IPv4(ipaddr) and true or false - end - - return false -end - -function main(argv) - local cmd = table.remove(argv, 1) - local arg = argv[1] - - limit_up = (tonumber(uci:get("luci_splash", "general", "limit_up")) or 0) * 8 - limit_down = (tonumber(uci:get("luci_splash", "general", "limit_down")) or 0) * 8 - - if ( cmd == "lease" or cmd == "add-rules" or cmd == "remove" or - cmd == "whitelist" or cmd == "blacklist" or cmd == "status" ) and #argv > 0 - then - if not (macvalid(arg) or ipvalid(arg)) then - print("Invalid argument. The second argument must " .. - "be a valid IPv4 or Mac Address.") - os.exit(1) - end - - lock() - - local arp_cache = net.arptable() - local leased_macs = get_known_macs("lease") - local blacklist_macs = get_known_macs("blacklist") - local whitelist_macs = get_known_macs("whitelist") - - for i, adr in ipairs(argv) do - local mac = nil - if adr:find(":") then - mac = adr:lower() - else - for _, e in ipairs(arp_cache) do - if e["IP address"] == adr then - mac = e["HW address"]:lower() - break - end - end - end - - if mac and cmd == "add-rules" then - if leased_macs[mac] then - add_lease(mac, arp_cache, true) - elseif blacklist_macs[mac] then - add_blacklist_rule(mac) - elseif whitelist_macs[mac] then - add_whitelist_rule(mac) - end - elseif mac and cmd == "status" then - print(leased_macs[mac] and "lease" - or whitelist_macs[mac] and "whitelist" - or blacklist_macs[mac] and "blacklist" - or "new") - elseif mac and ( cmd == "whitelist" or cmd == "blacklist" or cmd == "lease" ) then - if cmd ~= "lease" and leased_macs[mac] then - print("Removing %s from leases" % mac) - remove_lease(mac) - leased_macs[mac] = nil - end - - if cmd ~= "whitelist" and whitelist_macs[mac] then - if cmd == "lease" then - print('%s is whitelisted. Remove it before you can lease it.' % mac) - else - print("Removing %s from whitelist" % mac) - remove_whitelist(mac) - whitelist_macs[mac] = nil - end - end - - if cmd == "whitelist" and leased_macs[mac] then - print("Removing %s from leases" % mac) - remove_lease(mac) - leased_macs[mac] = nil - end - - if cmd ~= "blacklist" and blacklist_macs[mac] then - print("Removing %s from blacklist" % mac) - remove_blacklist(mac) - blacklist_macs[mac] = nil - end - - if cmd == "lease" and not leased_macs[mac] then - if not whitelist_macs[mac] then - print("Adding %s to leases" % mac) - add_lease(mac) - leased_macs[mac] = true - end - elseif cmd == "whitelist" and not whitelist_macs[mac] then - print("Adding %s to whitelist" % mac) - add_whitelist(mac) - whitelist_macs[mac] = true - elseif cmd == "blacklist" and not blacklist_macs[mac] then - print("Adding %s to blacklist" % mac) - add_blacklist(mac) - blacklist_macs[mac] = true - else - print("The mac %s is already %sed" %{ mac, cmd }) - end - elseif mac and cmd == "remove" then - if leased_macs[mac] then - print("Removing %s from leases" % mac) - remove_lease(mac) - leased_macs[mac] = nil - elseif whitelist_macs[mac] then - print("Removing %s from whitelist" % mac) - remove_whitelist(mac) - whitelist_macs[mac] = nil - elseif blacklist_macs[mac] then - print("Removing %s from blacklist" % mac) - remove_blacklist(mac) - blacklist_macs[mac] = nil - else - print("The mac %s is not known" % mac) - end - - else - print("Can not find mac for ip %s" % argv[i]) - end - end - unlock() - os.exit(0) - elseif cmd == "sync" then - sync() - os.exit(0) - elseif cmd == "list" then - list() - os.exit(0) - else - print("Usage:") - print("\n luci-splash list\n List connected, black- and whitelisted clients") - print("\n luci-splash sync\n Synchronize firewall rules and clear expired leases") - print("\n luci-splash lease <MAC-or-IP>\n Create a lease for the given address") - print("\n luci-splash blacklist <MAC-or-IP>\n Add given address to blacklist") - print("\n luci-splash whitelist <MAC-or-IP>\n Add given address to whitelist") - print("\n luci-splash remove <MAC-or-IP>\n Remove given address from the lease-, black- or whitelist") - print("") - - os.exit(1) - 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 not list or list == "lease" then - uci:foreach("luci_splash_leases", "lease", function(s) - if s.mac then - leased_macs[s.mac:lower()] = true - end - end) - end - - if not list or list == "whitelist" then - uci:foreach("luci_splash", "whitelist", function(s) - if s.mac then - leased_macs[s.mac:lower()] = true - end - end) - end - - if not list or list == "blacklist" then - uci:foreach("luci_splash", "blacklist", function(s) - if s.mac then - leased_macs[s.mac:lower()] = true - end - end) - end - return leased_macs -end - - --- Helper to delete iptables rules -function ipt_delete_all(args, comp, off) - off = off or { } - for i, r in ipairs(ipt:find(args)) do - if comp == nil or comp(r) then - 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] }) - - off[r.table][r.chain] = off[r.table][r.chain] + 1 - end - end -end - -function ipt6_delete_all(args, comp, off) - off = off or { } - for i, r in ipairs(ipt:find(args)) do - if comp == nil or comp(r) then - 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] }) - - off[r.table][r.chain] = off[r.table][r.chain] + 1 - end - end -end - - --- Convert mac to uci-compatible section name -function convert_mac_to_secname(mac) - return string.gsub(mac, ":", "") -end - --- Add a lease to state and invoke add_rule -function add_lease(mac, arp, no_uci) - mac = mac:lower() - - -- Get current ip address - local ipaddr - for _, entry in ipairs(arp or net.arptable()) do - if entry["HW address"]:lower() == mac then - ipaddr = entry["IP address"] - break - end - end - - -- Add lease if there is an ip addr - 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, - device = device, - limit_up = limit_up, - limit_down = limit_down, - start = os.time() - }) - uci:save("luci_splash_leases") - end - add_lease_rule(mac, ipaddr, device) - else - print("Found no active IP for %s, lease not added" % mac) - end -end - - --- Remove a lease from state and invoke remove_rule -function remove_lease(mac) - mac = mac:lower() - - uci:delete_all("luci_splash_leases", "lease", - function(s) - if s.mac:lower() == mac then - - 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 - remove_lease_rule(mac, s.ipaddr, s.device, tonumber(s.limit_up), tonumber(s.limit_down)) - return true - end - return false - end) - - uci:save("luci_splash_leases") -end - - --- Add a whitelist entry -function add_whitelist(mac) - uci:section("luci_splash", "whitelist", convert_mac_to_secname(mac), { mac = mac }) - uci:save("luci_splash") - uci:commit("luci_splash") - add_whitelist_rule(mac) -end - - --- Add a blacklist entry -function add_blacklist(mac) - uci:section("luci_splash", "blacklist", convert_mac_to_secname(mac), { mac = mac }) - uci:save("luci_splash") - uci:commit("luci_splash") - add_blacklist_rule(mac) -end - - --- Remove a whitelist entry -function remove_whitelist(mac) - mac = mac:lower() - uci:delete_all("luci_splash", "whitelist", - function(s) return not s.mac or s.mac:lower() == mac end) - uci:save("luci_splash") - uci:commit("luci_splash") - remove_lease_rule(mac) - remove_whitelist_tc(mac) -end - -function remove_whitelist_tc(mac) - uci:foreach("luci_splash", "iface", function(s) - local device = get_physdev(s['.name']) - if device and device ~= "" then - if debug then - print("Removing whitelist filters for %s interface %s." % {mac, device}) - 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 }) - 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 }) - else - print('Warning! Could not get a handle for %s parent 1:0 on interface %s' % { mac, device }) - end - end - end) -end - --- Remove a blacklist entry -function remove_blacklist(mac) - mac = mac:lower() - uci:delete_all("luci_splash", "blacklist", - function(s) return not s.mac or s.mac:lower() == mac end) - uci:save("luci_splash") - uci:commit("luci_splash") - remove_lease_rule(mac) -end - - --- Add an iptables rule -function add_lease_rule(mac, ipaddr, device) - local id - if ipaddr then - id = get_id(ipaddr) - end - - exec("iptables -t mangle -I luci_splash_mark_out -m mac --mac-source %q -j RETURN" % 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()}) - 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) - 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}) - 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}) - 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 }) - 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) - if has_ipv6 then - exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %q -j RETURN" % mac) - end -end - - --- Remove lease, black- or whitelist rules -function remove_lease_rule(mac, ipaddr, device, limit_up, limit_down) - - local id - if ipaddr then - id = get_id(ipaddr) - end - - ipt:resync() - ipt_delete_all({table="mangle", chain="luci_splash_mark_in", options={"/*", mac:upper()}}) - ipt_delete_all({table="mangle", chain="luci_splash_mark_out", options={"MAC", mac:upper()}}) - ipt_delete_all({table="filter", chain="luci_splash_filter", options={"MAC", mac:upper()}}) - ipt_delete_all({table="nat", chain="luci_splash_leases", options={"MAC", mac:upper()}}) - if has_ipv6 then - ipt6_delete_all({table="mangle", chain="luci_splash_mark_out", options={"MAC", mac:upper()}}) - ipt6_delete_all({table="filter", chain="luci_splash_filter", options={"MAC", mac:upper()}}) - 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}) - 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 }) - 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) - if has_ipv6 then - exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %q -j RETURN" % 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 }) - 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) - if has_ipv6 then - exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %q -j DROP" % mac) - end -end - - --- Synchronise leases, remove abandoned rules -function sync() - lock() - - local time = os.time() - - -- 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 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 - local leasecount = 0 - local leases_online = 0 - - -- For all leases - 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 - - -- only count leases_online for connected clients - if arpcache[v.mac] then - leases_online = leases_online + 1 - end - - -- Rewrite state - uci:section("luci_splash_leases", "lease", convert_mac_to_secname(v.mac), { - mac = v.mac, - ipaddr = v.ipaddr, - device = v.device, - limit_up = limit_up, - limit_down = limit_down, - start = v.start - }) - end - end - end - - -- 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 - - -- 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(leases_online, whitelist_online, whitelist_total, blacklist_online, blacklist_total) - - uci:save("luci_splash_leases") - - -- Get the mac addresses of current leases - local macs = get_known_macs() - - ipt:resync() - - ipt_delete_all({table="filter", chain="luci_splash_filter", options={"MAC"}}, - function(r) return not macs[r.options[2]:lower()] end) - ipt_delete_all({table="nat", chain="luci_splash_leases", options={"MAC"}}, - function(r) return not macs[r.options[2]:lower()] end) - ipt_delete_all({table="mangle", chain="luci_splash_mark_out", options={"MAC", "MARK", "set"}}, - function(r) return not macs[r.options[2]:lower()] end) - ipt_delete_all({table="mangle", chain="luci_splash_mark_in", options={"/*", "MARK", "set"}}, - function(r) return not macs[r.options[2]:lower()] end) - - - if has_ipv6 then - ipt6_delete_all({table="filter", chain="luci_splash_filter", options={"MAC"}}, - function(r) return not macs[r.options[2]:lower()] end) - ipt6_delete_all({table="mangle", chain="luci_splash_mark_out", options={"MAC", "MARK", "set"}}, - function(r) return not macs[r.options[2]:lower()] end) - end - - unlock() -end - --- Show client info -function list() - local arpcache = get_arpcache() - -- Find traffic usage - local function traffic(lease) - local traffic_in = 0 - local traffic_out = 0 - - local rin = ipt:find({table="mangle", chain="luci_splash_mark_in", destination=lease.ipaddr}) - local rout = ipt:find({table="mangle", chain="luci_splash_mark_out", options={"MAC", lease.mac:upper()}}) - - if rin and #rin > 0 then traffic_in = math.floor( rin[1].bytes / 1024) end - if rout and #rout > 0 then traffic_out = math.floor(rout[1].bytes / 1024) end - - return traffic_in, traffic_out - end - - -- 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", - "MAC", "IP", "State", "Dur.", "Intf.", "Traffic down/up" - )) - - -- Leases - for _, s in pairs(leases) do - if s[".type"] == "lease" and s.mac then - local ti, to = traffic(s) - local mac = s.mac:lower() - local arp = arpcache[mac] - print(string.format( - "%-17s %-15s %-9s %3dm %-7s %7dKB %7dKB", - mac, s.ipaddr, "leased", - math.floor(( os.time() - tonumber(s.start) ) / 60), - arp and arp[1] or "?", ti, to - )) - end - end - - -- Whitelist, Blacklist - 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() - local arp = arpcache[mac] - print(string.format( - "%-17s %-15s %-9s %4s %-7s %9s %9s", - mac, arp and arp[2] or "?", s[".type"], - "- ", arp and arp[1] or "?", "-", "-" - )) - end - end -end - -main(arg) |