afde3fdf9100f045eb39cc12ca5a23a85065a364
[project/luci.git] / applications / luci-ffwizard-leipzig / luasrc / model / cbi / ffwizard.lua
1 --[[
2 LuCI - Lua Configuration Interface
3
4 Copyright 2008 Steven Barth <steven@midlink.org>
5 Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
6
7 Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
10
11 http://www.apache.org/licenses/LICENSE-2.0
12
13 $Id$
14
15 ]]--
16
17
18 local uci = require "luci.model.uci".cursor()
19 local tools = require "luci.tools.ffwizard"
20
21
22 -------------------- View --------------------
23 f = SimpleForm("ffwizward", "Freifunkassistent",
24  "Dieser Assistent unterstüzt bei der Einrichtung des Routers für das Freifunknetz.")
25
26
27 dev = f:field(ListValue, "device", "WLAN-Gerät")
28 uci:foreach("wireless", "wifi-device",
29         function(section)
30                 dev:value(section[".name"])
31         end)
32
33
34 main = f:field(Flag, "wifi", "Freifunkzugang einrichten")
35
36 net = f:field(Value, "net", "Freifunknetz")
37 net.rmempty = true
38 net:depends("wifi", "1")
39 uci:foreach("freifunk", "community", function(s)
40         net:value(s[".name"], s.name)
41 end)
42
43 function net.cfgvalue(self, section)
44         return uci:get("freifunk", "wizard", "net")
45 end
46 function net.write(self, section, value)
47         uci:set("freifunk", "wizard", "net", value)
48         uci:save("freifunk")
49 end
50
51
52 subnet = f:field(Value, "subnet", "Subnetz (Projekt)")
53 subnet.rmempty = true
54 subnet:depends("wifi", "1")
55 function subnet.cfgvalue(self, section)
56         return uci:get("freifunk", "wizard", "subnet")
57 end
58 function subnet.write(self, section, value)
59         uci:set("freifunk", "wizard", "subnet", value)
60         uci:save("freifunk")
61 end
62
63 node = f:field(Value, "node", "Knoten")
64 node.rmempty = true
65 node:depends("wifi", "1")
66 for i=1, 51 do
67         node:value(i)
68 end
69 function node.cfgvalue(self, section)
70         return uci:get("freifunk", "wizard", "node")
71 end
72 function node.write(self, section, value)
73         uci:set("freifunk", "wizard", "node", value)
74         uci:save("freifunk")
75 end
76
77 client = f:field(Flag, "client", "WLAN-DHCP anbieten")
78 client:depends("wifi", "1")
79
80
81 olsr = f:field(Flag, "olsr", "OLSR einrichten")
82
83 share = f:field(ListValue, "sharenet", "Eigenen Internetzugang freigeben")
84 share:value("maybe", "-- keine Aktion --")
85 share:value("yes", "einschalten")
86 share:value("no", "ausschalten")
87
88
89
90 -------------------- Control --------------------
91 function f.handle(self, state, data)
92         if state == FORM_VALID then
93                 luci.http.redirect(luci.dispatcher.build_url("admin", "uci", "changes"))
94                 return false
95         elseif state == FORM_INVALID then
96                 self.errmessage = "Ungültige Eingabe: Bitte die Formularfelder auf Fehler prüfen."
97         end
98         return true
99 end
100
101 local function _strip_internals(tbl)
102         tbl = tbl or {}
103         for k, v in pairs(tbl) do
104                 if k:sub(1, 1) == "." then
105                         tbl[k] = nil
106                 end
107         end
108         return tbl
109 end
110
111 -- Configure Freifunk checked
112 function main.write(self, section, value)
113         if value == "0" then
114                 return
115         end
116
117         local device = dev:formvalue(section)
118         local community
119
120         -- Collect IP-Address
121         local inet = net:formvalue(section)
122         local isubnet = subnet:formvalue(section)
123         local inode = node:formvalue(section)
124
125         -- Invalidate fields
126         if not inet then
127                 net.tag_missing[section] = true
128         else
129                 community = inet
130                 inet = uci:get("freifunk", community, "prefix") or inet
131         end
132         if not isubnet then
133                 subnet.tag_missing[section] = true
134         end
135         if not inode then
136                 node.tag_missing[section] = true
137         end
138
139         if not inet or not isubnet or not inode then
140                 return
141         end
142
143         local ip = "%s.%s.%s" % {inet, isubnet, inode}
144
145
146         -- Cleanup
147         tools.wifi_delete_ifaces(device)
148         tools.network_remove_interface(device)
149         tools.firewall_zone_remove_interface("freifunk", device)
150         
151         -- Tune community settings
152         if community then
153                 uci:tset("freifunk", "community", uci:get_all("freifunk", community))
154         end
155
156         -- Tune wifi device
157         local devconfig = _strip_internals(uci:get_all("freifunk", "wifi_device"))
158         uci:tset("wireless", device, devconfig)
159
160         -- Create wifi iface
161         local ifconfig = _strip_internals(uci:get_all("freifunk", "wifi_iface"))
162         ifconfig.device = device
163         ifconfig.network = device
164         ifconfig.ssid = uci:get("freifunk", community, "ssid")
165         uci:section("wireless", "wifi-iface", nil, ifconfig)
166
167         -- Save wifi
168         uci:save("wireless")
169
170         -- Create firewall zone and add default rules (first time)
171         local newzone = tools.firewall_create_zone("freifunk", "DROP", "ACCEPT", "DROP", true)
172         if newzone then
173                 uci:foreach("freifunk", "fw_forwarding", function(section)
174                         uci:section("firewall", "forwarding", nil, _strip_internals(section))
175                 end)
176
177                 uci:foreach("freifunk", "fw_rule", function(section)
178                         uci:section("firewall", "rule", nil, _strip_internals(section))
179                 end)
180
181                 uci:save("firewall")
182         end
183
184
185         -- Crate network interface
186         local netconfig = _strip_internals(uci:get_all("freifunk", "interface"))
187         netconfig.proto = "static"
188         netconfig.ipaddr = ip
189         uci:section("network", "interface", device, netconfig)
190
191         uci:save("network")
192
193         tools.firewall_zone_add_interface("freifunk", device)
194 end
195
196
197 function olsr.write(self, section, value)
198         if value == "0" then
199                 return
200         end
201
202         local device = dev:formvalue(section)
203
204         -- Delete old interface
205         uci:delete_all("freifunk", "Interface", {Interface=device})
206
207         -- Write new interface
208         local olsrbase = _strip_internals(uci:get_all("freifunk", "olsr_interface"))
209         olsrbase.interface = device
210         olsrbase.ignore    = "0"
211         uci:section("olsrd", "Interface", nil, olsrbase)
212         uci:save("olsrd")
213 end
214
215
216 function share.write(self, section, value)
217         if value == "maybe" then
218                 return
219         end
220
221         uci:delete_all("firewall", "forwarding", {src="freifunk", dest="wan"})
222
223         if value == "yes" then
224                 uci:section("firewall", "forwarding", nil, {src="freifunk", dest="wan"})
225         end
226         uci:save("firewall")
227 end
228
229
230 function client.write(self, section, value)
231         if value == "0" then
232                 return
233         end
234
235         local device = dev:formvalue(section)
236
237         -- Collect IP-Address
238         local inet = net:formvalue(section)
239         local isubnet = subnet:formvalue(section)
240         local inode = node:formvalue(section)
241
242         if not inet or not isubnet or not inode then
243                 return
244         end
245         
246         inet = uci:get("freifunk", inet, "prefix") or inet
247
248         local dhcpbeg = 48 + tonumber(inode) * 4
249         local dclient = "%s.%s.%s" % {inet:gsub("^[0-9]+", "10"), isubnet, dhcpbeg}
250         local limit = dhcpbeg < 252 and 3 or 2
251
252         -- Delete old alias
253         uci:delete("network", device .. "dhcp")
254
255         -- Create alias
256         local aliasbase = _strip_internals(uci:get_all("freifunk", "alias"))
257         aliasbase.interface = device
258         aliasbase.ipaddr = dclient
259         aliasbase.proto = "static"
260         uci:section("network", "alias", device .. "dhcp", aliasbase)
261         uci:save("network")
262
263
264         -- Create dhcp
265         local dhcpbase = _strip_internals(uci:get_all("freifunk", "dhcp"))
266         dhcpbase.interface = device .. "dhcp"
267         dhcpbase.start = dhcpbeg
268         dhcpbase.limit = limit
269
270         uci:section("dhcp", "dhcp", device .. "dhcp", dhcpbase)
271         uci:save("dhcp")
272         
273         uci:delete_all("firewall", "rule", {
274                 src="freifunk",
275                 proto="udp",
276                 src_port="68",
277                 dest_port="67"
278         })
279         uci:section("firewall", "rule", nil, {
280                 src="freifunk",
281                 proto="udp",
282                 src_port="68",
283                 dest_port="67",
284                 target="ACCEPT"
285         })
286         
287
288
289         -- Delete old splash
290         uci:delete_all("luci_splash", "iface", {net=device, zone="freifunk"})
291
292         -- Register splash
293         uci:section("luci_splash", "iface", nil, {net=device, zone="freifunk"})
294         uci:save("luci_splash")
295 end
296
297 return f