* Added initial version of RPC info API

* Fixed client splash
This commit is contained in:
Steven Barth 2008-04-27 16:12:24 +00:00
parent 1b159023db
commit bba585f063
18 changed files with 180 additions and 51 deletions

View file

@ -10,7 +10,6 @@ require("ffluci.model.uci")
uci = ffluci.model.uci.Session("/var/state") uci = ffluci.model.uci.Session("/var/state")
-- Parse stdin and do something
function main(argv) function main(argv)
local cmd = argv[1] local cmd = argv[1]
local arg = argv[2] local arg = argv[2]
@ -156,7 +155,7 @@ function sync()
local n = uci:add("luci_splash", "lease") local n = uci:add("luci_splash", "lease")
uci:set("luci_splash", n, "mac", v.mac) uci:set("luci_splash", n, "mac", v.mac)
uci:set("luci_splash", n, "start", v.start) uci:set("luci_splash", n, "start", v.start)
written[v.mac] = 1 written[v.mac:lower()] = 1
end end
end end
end end
@ -164,7 +163,7 @@ function sync()
-- Delete rules without state -- Delete rules without state
for i, r in ipairs(listrules()) do for i, r in ipairs(listrules()) do
if #r > 0 and not written[r] then if #r > 0 and not written[r:lower()] then
remove_rule(r) remove_rule(r)
end end
end end

View file

@ -7,22 +7,35 @@ require("ffluci.sys")
require("ffluci.model.uci") require("ffluci.model.uci")
local srv local srv
local net
local ip = ffluci.http.remote_addr() local ip = ffluci.http.remote_addr()
for k, v in pairs(ffluci.model.uci.show("network").network) do for k, v in pairs(ffluci.model.uci.show("network").network) do
if v[".type"] == "interface" and v.ipaddr then if v[".type"] == "interface" and v.ipaddr then
local p = ffluci.sys.net.mask4prefix(v.netmask) local p = ffluci.sys.net.mask4prefix(v.netmask)
if ffluci.sys.net.belongs(ip, v.ipaddr, p) then if ffluci.sys.net.belongs(ip, v.ipaddr, p) then
net = k
srv = v.ipaddr srv = v.ipaddr
break break
end end
end end
end end
local stat = false
for k, v in pairs(ffluci.model.uci.show("luci_splash").luci_splash) do
if v[".type"] == "iface" and v.network == net then
stat = true
end
end
if not srv then if not srv then
ffluci.http.textheader() ffluci.http.textheader()
return print("Unable to detect network settings!") return print("Unable to detect network settings!")
end end
if not stat then
ffluci.http.redirect("http://" .. srv)
end
local action = "splash" local action = "splash"
local mac = ffluci.sys.net.ip4mac(ip) local mac = ffluci.sys.net.ip4mac(ip)
@ -30,7 +43,7 @@ if not mac then
action = "unknown" action = "unknown"
end end
local status = ffluci.sys.exec("luci-splash status "..mac) local status = ffluci.sys.execl("luci-splash status "..mac)[1]
if status == "whitelisted" or status == "lease" then if status == "whitelisted" or status == "lease" then
action = "allowed" action = "allowed"

View file

@ -20,7 +20,7 @@ iface_add() {
eval "$(ipcalc.sh $ipaddr $netmask)" eval "$(ipcalc.sh $ipaddr $netmask)"
iptables -t nat -A luci_splash -i "$iface" -s "$IP/$PREFIX" -j luci_splash_portal iptables -t nat -A luci_splash -i "$iface" -s "$IP/$PREFIX" -j luci_splash_portal
iptables -t nat -A luci_splash_portal -i "$iface" -s "$IP/$PREFIX" -d "$ipaddr" -p tcp --dport 80 -j RETURN iptables -t nat -A luci_splash_portal -i "$iface" -s "$IP/$PREFIX" -d "$ipaddr" -p tcp -m multiport --dports 22,80,443 -j RETURN
} }
blacklist_add() { blacklist_add() {
@ -64,9 +64,6 @@ start() {
### Start the splash httpd ### Start the splash httpd
httpd -c /etc/luci_splash_httpd.conf -p 8082 -h /usr/lib/luci-splash/htdocs httpd -c /etc/luci_splash_httpd.conf -p 8082 -h /usr/lib/luci-splash/htdocs
### Sync leases
/usr/lib/luci-splash/sync.lua
### Hook in the chain ### Hook in the chain
iptables -t nat -A prerouting_rule -j luci_splash iptables -t nat -A prerouting_rule -j luci_splash
} }

View file

@ -37,6 +37,7 @@ define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR)/core $(MAKE_ACTION) $(MAKE) -C $(PKG_BUILD_DIR)/core $(MAKE_ACTION)
$(MAKE) -C $(PKG_BUILD_DIR)/module/admin-core $(MAKE_ACTION) $(MAKE) -C $(PKG_BUILD_DIR)/module/admin-core $(MAKE_ACTION)
$(MAKE) -C $(PKG_BUILD_DIR)/module/public-core $(MAKE_ACTION) $(MAKE) -C $(PKG_BUILD_DIR)/module/public-core $(MAKE_ACTION)
$(MAKE) -C $(PKG_BUILD_DIR)/module/rpc-core $(MAKE_ACTION)
endef endef
define Package/ffluci/install define Package/ffluci/install
@ -66,6 +67,8 @@ define Package/ffluci/install
$(CP) $(PKG_BUILD_DIR)/module/public-core/dist/* $(1)/usr/lib/lua/ffluci/ -R $(CP) $(PKG_BUILD_DIR)/module/public-core/dist/* $(1)/usr/lib/lua/ffluci/ -R
$(CP) $(PKG_BUILD_DIR)/module/public-core/contrib/media $(1)/www/ffluci/ -R $(CP) $(PKG_BUILD_DIR)/module/public-core/contrib/media $(1)/www/ffluci/ -R
$(CP) $(PKG_BUILD_DIR)/module/rpc-core/dist/* $(1)/usr/lib/lua/ffluci/ -R
$(CP) -a ./ipkg/ffluci.postinst $(1)/CONTROL/postinst $(CP) -a ./ipkg/ffluci.postinst $(1)/CONTROL/postinst
$(CP) -a ./ipkg/conffiles $(1)/CONTROL/conffiles $(CP) -a ./ipkg/conffiles $(1)/CONTROL/conffiles
rm $(DL_DIR)/$(PKG_SOURCE) rm $(DL_DIR)/$(PKG_SOURCE)

View file

@ -27,6 +27,8 @@ limitations under the License.
]]-- ]]--
ENV = ENV or {}
FORM = FORM or {}
module("ffluci.http", package.seeall) module("ffluci.http", package.seeall)
require("ffluci.util") require("ffluci.util")

View file

@ -52,6 +52,13 @@ end
-- The default Session -- The default Session
local default = Session() local default = Session()
local state = Session("/var/state")
-- The state Session
function StateSession()
return state
end
-- Wrapper for "uci add" -- Wrapper for "uci add"
function Session.add(self, config, section_type) function Session.add(self, config, section_type)
@ -114,8 +121,8 @@ end
-- Wrapper for "uci show" -- Wrapper for "uci show"
function Session.show(self, config) function Session.show(self, config, ...)
return self:_uci3("show " .. _path(config)) return self:_uci3("show " .. _path(config), ...)
end end
function show(...) function show(...)
@ -155,11 +162,15 @@ function Session._uci2(self, cmd)
end end
end end
function Session._uci3(self, cmd) function Session._uci3(self, cmd, raw)
local res = ffluci.sys.execl(self.ucicmd .. " 2>&1 " .. cmd) local res = ffluci.sys.execl(self.ucicmd .. " 2>&1 " .. cmd)
if res[1] and res[1]:sub(1, self.ucicmd:len()+1) == self.ucicmd..":" then if res[1] and res[1]:sub(1, self.ucicmd:len()+1) == self.ucicmd..":" then
return nil, res[1] return nil, res[1]
end end
if raw then
return table.concat(res, "\n")
end
tbl = {} tbl = {}

View file

@ -29,6 +29,13 @@ require("posix")
require("ffluci.bits") require("ffluci.bits")
require("ffluci.util") require("ffluci.util")
-- Returns whether a system is bigendian
function bigendian()
local fp = io.open("/bin/sh")
fp:seek("set", 5)
return (fp:read(1):byte() ~= 1)
end
-- Runs "command" and returns its output -- Runs "command" and returns its output
function exec(command) function exec(command)
local pp = io.popen(command) local pp = io.popen(command)
@ -125,6 +132,20 @@ function net.belongs(ip, ipnet, prefix)
return (net.ip4bin(ip):sub(1, prefix) == net.ip4bin(ipnet):sub(1, prefix)) return (net.ip4bin(ip):sub(1, prefix) == net.ip4bin(ipnet):sub(1, prefix))
end end
-- Detect the default route
function net.defaultroute()
local routes = net.routes()
local route = nil
for i, r in pairs(ffluci.sys.net.routes()) do
if r.Destination == "00000000" and (not route or route.Metric > r.Metric) then
route = r
end
end
return route
end
-- Returns all available network interfaces -- Returns all available network interfaces
function net.devices() function net.devices()
local devices = {} local devices = {}
@ -163,16 +184,18 @@ function net.routes()
return _parse_delimited_table(io.lines("/proc/net/route")) return _parse_delimited_table(io.lines("/proc/net/route"))
end end
-- Returns the numeric IP to a given hexstring (little endian) -- Returns the numeric IP to a given hexstring
function net.hexip4(hex, bigendian) function net.hexip4(hex, be)
if #hex ~= 8 then if #hex ~= 8 then
return nil return nil
end end
be = be or bigendian()
local hexdec = ffluci.bits.Hex2Dec local hexdec = ffluci.bits.Hex2Dec
local ip = "" local ip = ""
if bigendian then if be then
ip = ip .. tostring(hexdec(hex:sub(1,2))) .. "." ip = ip .. tostring(hexdec(hex:sub(1,2))) .. "."
ip = ip .. tostring(hexdec(hex:sub(3,4))) .. "." ip = ip .. tostring(hexdec(hex:sub(3,4))) .. "."
ip = ip .. tostring(hexdec(hex:sub(5,6))) .. "." ip = ip .. tostring(hexdec(hex:sub(5,6))) .. "."

View file

@ -13,7 +13,7 @@ function action_apply()
-- Collect files to be applied -- Collect files to be applied
for i, line in ipairs(ffluci.util.split(changes)) do for i, line in ipairs(ffluci.util.split(changes)) do
local r = line:match("^-?([^.]+)") local r = line:match("^-?([^.]+)")
if r then if r and not ffluci.util.contains(apply, ffluci.config.uci_oncommit[r]) then
table.insert(apply, ffluci.config.uci_oncommit[r]) table.insert(apply, ffluci.config.uci_oncommit[r])
end end
end end

View file

@ -1,9 +1,13 @@
module("ffluci.controller.public.splash", package.seeall) module("ffluci.controller.splash.splash", package.seeall)
function action_activate() function action_activate()
local mac = ffluci.sys.net.ip4mac(ffluci.http.remote_addr()) local mac = ffluci.sys.net.ip4mac(ffluci.http.remote_addr())
os.execute("luci-splash add "..mac) if mac and ffluci.http.formvalue("accept") then
ffluci.http.request_redirect() os.execute("luci-splash add "..mac.." >/dev/null 2>&1")
ffluci.http.redirect(ffluci.model.uci.get("freifunk", "community", "homepage"))
else
ffluci.http.request_redirect()
end
end end
function action_accepted() function action_accepted()

View file

@ -5,7 +5,7 @@ Diese Informationen sollten nach der Picopeering Vereinbarung mindestens deine E
Damit dein Knoten durch Topographieprogramme erfasst werden kann, gib bitte deine Geokoordinaten oder Damit dein Knoten durch Topographieprogramme erfasst werden kann, gib bitte deine Geokoordinaten oder
zumindest deine Straße und Hausnummer unter Standort an.]])) zumindest deine Straße und Hausnummer unter Standort an.]]))
c = m:section(NamedSection, "contact") c = m:section(NamedSection, "contact", "public")
c:option(Value, "nickname", translate("nickname", "Pseudonym")) c:option(Value, "nickname", translate("nickname", "Pseudonym"))
c:option(Value, "name", translate("name", "Name")) c:option(Value, "name", translate("name", "Name"))

View file

@ -0,0 +1,13 @@
-- Todo: Translate
m = Map("freifunk", "Freifunk", [[Informationen über die lokale Freifunkgemeinschaft.]])
c = m:section(NamedSection, "community", "public")
c:option(Value, "name", "Gemeinschaft")
c:option(Value, "homepage", "Webseite")
c:option(Value, "essid", "ESSID")
c:option(Value, "bssid", "BSSID")
c:option(Value, "realm", "Realm")
c:option(Value, "pool", "Adressbereich")
return m

View file

@ -1,6 +1,7 @@
add("admin", "index", "Übersicht", 10) add("admin", "index", "Übersicht", 10)
act("contact", "Kontakt") act("contact", "Kontakt")
act("luci", "Oberfläche") act("luci", "Oberfläche")
act("freifunk", "Freifunk")
add("admin", "system", "System", 30) add("admin", "system", "System", 30)
act("packages", "Paketverwaltung") act("packages", "Paketverwaltung")

View file

@ -1,23 +1,31 @@
<h1><%:welcome Willkommen%>!</h1>
<p>
Du bist jetzt mit dem freien Funknetz Du bist jetzt mit dem freien Funknetz
<a href="<%~freifunk.community.homepage%>"><%~freifunk.community.name%></a> <a href="<%~freifunk.community.homepage%>"><%~freifunk.community.name%></a> verbunden.<br />
verbunden. Wir sind ein experimentelles Gemeinschaftsnetzwerk, aber kein Internetanbieter. Wir sind ein experimentelles Gemeinschaftsnetzwerk, aber kein Internetanbieter.
</p>
<br />
<p>
Ein Zugang <strong>ins Internet</strong> ist trotzdem möglich, Ein Zugang <strong>ins Internet</strong> ist trotzdem möglich,
da einige Freifunker ihre privaten Internetzugänge zur Verfügung stellen. da einige Freifunker ihre privaten Internetzugänge zur Verfügung stellen.
Diese Zugänge müssen sich hier alle teilen. Diese Zugänge müssen sich hier alle teilen.
Bitte sei Dir dessen bewusst und verhalte Dich dementsprechend: Bitte sei Dir dessen bewusst und verhalte Dich dementsprechend:
<ul> <ul>
<li>bitte keine Filesharing-Programme betreiben!</li> <li>bitte <strong>keine Filesharing-Programme</strong> betreiben!</li>
<li>bitte keine unnötigen Downloads bzw. Streams starten</li> <li>bitte <strong>keine unnötigen Downloads oder Streams</strong> starten!</li>
<li>bitte keine illegalen Sachen machen</li> <li>bitte <strong>keine illegalen Aktivitäten</strong>!</li>
</ul> </ul>
</p>
<p> <p>
Wenn Du unsere Idee gut findest, kannst Du mitmachen bzw. uns unterstützen: Wenn Du unsere Idee gut findest, kannst Du uns unterstützen:
<ul> <ul>
<li>Werde selbst Freifunker oder teile deinen Internetzugang!</li> <li><a href="<%~freifunk.community.homepage%>">Werde selbst Freifunker oder teile deinen Internetzugang!</a></li>
<li>Betreibe deine anderen WLAN-Geräte <em>NICHT</em> auf den Kanälen 1-5, diese stören oft das Freifunk-Netz.</li> <li>Betreibe deine anderen WLAN-Geräte <em>NICHT</em> auf den Kanälen 1-5, diese stören oft unser Netz.</li>
</ul> </ul>
</p>
<p>
Mit einem Klick auf <em><%:accept Annehmen%></em> kannst du für <%~luci_splash.general.leasetime%> Stunden
über unser Netz das Internet verwenden. Dann wirst du erneut aufgefordet, diese Bedingungen zu akzeptieren.
</p> </p>

View file

@ -1,6 +1,7 @@
<%+header%> <%+header%>
<%+splash/splash%> <%+splash/splash%>
<form method="post" action="<%=controller%>/splash/splash/activate"> <form method="get" action="<%=controller%>/splash/splash/activate">
<input type="submit" value="<%:accept Annehmen%>" /> <input type="submit" value="<%:decline Ablehnen%>" />
<input type="submit" name="accept" value="<%:accept Annehmen%>" />
</form> </form>
<%+footer%> <%+footer%>

View file

@ -47,19 +47,10 @@
<th><%:iface Schnittstelle%></th> <th><%:iface Schnittstelle%></th>
</tr> </tr>
<% <%
-- UGLY hack is UGLY
if routes[1] and routes[1].Gateway:sub(-2) == "00" then
local be = true
else
local be = false
end
for i, rt in pairs(routes) do for i, rt in pairs(routes) do
%> %>
<tr> <tr>
<td><%=ffluci.sys.net.hexip4(rt.Gateway, be)%></th> <td><%=ffluci.sys.net.hexip4(rt.Gateway)%></th>
<td><%=rt.Metric%></th> <td><%=rt.Metric%></th>
<td><%=rt.Iface%></th> <td><%=rt.Iface%></th>
</tr> </tr>

View file

@ -13,19 +13,12 @@
<% <%
local routes = ffluci.sys.net.routes() local routes = ffluci.sys.net.routes()
-- UGLY hack is UGLY
if routes[1] and routes[1].Gateway:sub(-2) == "00" then
local be = true
else
local be = false
end
for i, r in pairs(routes) do for i, r in pairs(routes) do
%> %>
<tr> <tr>
<td><%=ffluci.sys.net.hexip4(r.Destination, be)%></td> <td><%=ffluci.sys.net.hexip4(r.Destination)%></td>
<td><%=ffluci.sys.net.hexip4(r.Mask, be)%></td> <td><%=ffluci.sys.net.hexip4(r.Mask)%></td>
<td><%=ffluci.sys.net.hexip4(r.Gateway, be)%></td> <td><%=ffluci.sys.net.hexip4(r.Gateway)%></td>
<td><%=r.Metric%></td> <td><%=r.Metric%></td>
<td><%=r.Iface%></td> <td><%=r.Iface%></td>
</tr> </tr>

35
module/rpc-core/Makefile Normal file
View file

@ -0,0 +1,35 @@
LUAC = luac
LUAC_OPTIONS = -s
FILES = i18n/* view/*/*.htm
CFILES = controller/*/*.lua model/cbi/*/*.lua model/menu/*.lua
DIRECTORIES = model/cbi model/menu controller i18n view
INFILES = $(CFILES:%=src/%)
OUTDIRS = $(DIRECTORIES:%=dist/%)
CPFILES = $(FILES:%=src/%)
.PHONY: all compile source clean depends
all: compile
depends:
mkdir -p $(OUTDIRS)
for i in $(CPFILES); do if [ -f "$$i" ]; then i=$$(echo $$i | cut -d/ -f2-); \
mkdir -p dist/$$(dirname $$i); cp src/$$i dist/$$i; fi; done
compile: depends
for i in $(INFILES); do if [ -f "$$i" ]; then i=$$(echo $$i | cut -d/ -f2-); \
mkdir -p dist/$$(dirname $$i); $(LUAC) $(LUAC_OPTIONS) -o dist/$$i src/$$i; fi; done
source: depends
for i in $(INFILES); do if [ -f "$$i" ]; then i=$$(echo $$i | cut -d/ -f2-); \
mkdir -p dist/$$(dirname $$i); cp src/$$i dist/$$i; fi; done
clean:
rm dist -rf

View file

@ -0,0 +1,35 @@
module("ffluci.controller.rpc.luciinfo", package.seeall)
function action_index()
local uci = ffluci.model.uci.StateSession()
ffluci.http.textheader()
-- General
print("luciinfo.api=1")
print("luciinfo.version=" .. tostring(ffluci.__version__))
-- Sysinfo
local s, m, r = ffluci.sys.sysinfo()
local dr = ffluci.sys.net.defaultroute()
dr = dr and ffluci.sys.net.hexip4(dr.Gateway) or ""
local l1, l5, l15 = ffluci.sys.loadavg()
print("sysinfo.system=" .. sanitize(s))
print("sysinfo.cpu=" .. sanitize(m))
print("sysinfo.ram=" .. sanitize(r))
print("sysinfo.hostname=" .. sanitize(ffluci.sys.hostname()))
print("sysinfo.load1=" .. tostring(l1))
print("sysinfo.load5=" .. tostring(l5))
print("sysinfo.load15=" .. tostring(l15))
print("sysinfo.defaultgw=" .. dr)
-- Freifunk
local ff = uci:show("freifunk", true) or ""
print(ff)
end
function sanitize(val)
return val:gsub("\n", "\t")
end