0cc26e5928a105f58fca142fd73c06ec8a4fbaa1
[project/luci.git] / applications / luci-ffwizard / 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 Copyright 2011 Patrick Grimm <patrick@pberg.freifunk.net>
7
8 Licensed under the Apache License, Version 2.0 (the "License");
9 you may not use this file except in compliance with the License.
10 You may obtain a copy of the License at
11
12 http://www.apache.org/licenses/LICENSE-2.0
13
14 $Id$
15
16 ]]--
17
18
19 local uci = require "luci.model.uci".cursor()
20 local uci_state = require "luci.model.uci".cursor_state()
21 local tools = require "luci.tools.ffwizard"
22 local util = require "luci.util"
23 local sys = require "luci.sys"
24 local ip = require "luci.ip"
25 local fs  = require "nixio.fs"
26
27 local has_pptp  = fs.access("/usr/sbin/pptp")
28 local has_pppoe = fs.glob("/usr/lib/pppd/*/rp-pppoe.so")()
29 local has_l2gvpn  = fs.access("/usr/sbin/node")
30 local has_radvd  = fs.access("/etc/config/radvd")
31 local has_rom  = fs.access("/rom/etc")
32 local has_autoipv6  = fs.access("/usr/bin/auto-ipv6")
33 local has_qos  = fs.access("/etc/init.d/qos")
34 local has_ipv6 = fs.access("/proc/sys/net/ipv6")
35 local has_hb = fs.access("/sbin/heartbeat")
36
37 luci.i18n.loadc("freifunk")
38
39 function get_mac(ix)
40         if string.find(ix, "radio") then
41                 ix = string.gsub(ix,"radio", 'wlan')
42         end
43         local mac = fs.readfile("/sys/class/net/" .. ix .. "/address")
44         if not mac then
45                 mac = luci.util.exec("ifconfig " .. ix)
46                 mac = mac and mac:match(" ([A-F0-9:]+)%s*\n")
47         else
48                 mac = mac:sub(1,17)
49         end
50         if mac and #mac > 0 then
51                 return mac:lower()
52         end
53         return "?"
54 end
55 function get_ula(imac)
56         if string.len(imac) == 17 then
57                 local mac1 = string.sub(imac,4,8)
58                 local mac2 = string.sub(imac,10,14)
59                 local mac3 = string.sub(imac,16,17)
60                 return 'fdca:ffee:babe::02'..mac1..'ff:fe'..mac2..mac3..'/64'
61         end
62         return "?"
63 end
64
65
66 -------------------- View --------------------
67 f = SimpleForm("ffwizward", "Freifunkassistent",
68  "Dieser Assistent unterstützt Sie bei der Einrichtung des Routers für das Freifunknetz.")
69
70 -- if password is not set or default then force the user to set a new one
71 if sys.exec("diff /rom/etc/passwd /etc/passwd") == "" then
72         pw1 = f:field(Value, "pw1", translate("password"))
73         pw1.password = true
74         pw1.rmempty = false
75
76         pw2 = f:field(Value, "pw2", translate("confirmation"))
77         pw2.password = true
78         pw2.rmempty = false
79
80         function pw2.validate(self, value, section)
81                 return pw1:formvalue(section) == value and value
82         end
83 end
84
85 net = f:field(ListValue, "net", "Freifunk Community", "Nutzen Sie die Einstellungen der Freifunk Gemeinschaft in ihrer Nachbarschaft.")
86 net.rmempty = false
87 net.optional = false
88 uci:foreach("freifunk", "community", function(s)
89         net:value(s[".name"], "%s (%s)" % {s.name, s.mesh_network or "?"})
90 end)
91 function net.cfgvalue(self, section)
92         return uci:get("freifunk", "wizard", "net")
93 end
94 function net.write(self, section, value)
95         uci:set("freifunk", "wizard", "net", value)
96         uci:save("freifunk")
97 end
98 net_lat = f:field(ListValue, "net_lat", "", "")
99 net_lat:depends("net", "0")
100 net_lon = f:field(ListValue, "net_lon", "", "")
101 net_lon:depends("net", "0")
102
103 uci:foreach("freifunk", "community", function(s)
104         if s.latitude then
105                 net_lat:value(s[".name"], "%s" % {s.latitude or "?"})
106         end
107         if s.longitude then
108                 net_lon:value(s[".name"], "%s" % {s.longitude or "?"})
109         end
110 end)
111
112 -- hostname
113 hostname = f:field(Value, "hostname", "Knoten Name", "Geben Sie Ihrem Freifunk Router einen Namen. Wenn Sie dieses Feld leer lassen, wird der Name automatisch aus der Mesh IP generiert.")
114 hostname.rmempty = true
115 hostname.optional = false
116 function hostname.cfgvalue(self, section)
117         return sys.hostname()
118 end
119 function hostname.write(self, section, value)
120         uci:set("freifunk", "wizard", "hostname", value)
121         uci:save("freifunk")
122 end
123 function hostname.validate(self, value)
124         if (#value > 16) then
125                 return
126         elseif (string.find(value, "[^%w%_%-]")) then
127                 return
128         else
129                 return value
130         end
131 end
132
133 -- location
134 location = f:field(Value, "location", "Standort", "Geben Sie den Standort ihres Gerätes an")
135 location.rmempty = false
136 location.optional = false
137 function location.cfgvalue(self, section)
138         return uci:get("freifunk", "contact", "location")
139 end
140 function location.write(self, section, value)
141         uci:set("freifunk", "contact", "location", value)
142         uci:save("freifunk")
143 end
144
145 -- mail
146 mail = f:field(Value, "mail", "E-Mail", "Bitte hinterlegen Sie eine Kontaktadresse.")
147 mail.rmempty = false
148 mail.optional = false
149 function mail.cfgvalue(self, section)
150         return uci:get("freifunk", "contact", "mail")
151 end
152 function mail.write(self, section, value)
153         uci:set("freifunk", "contact", "mail", value)
154         uci:save("freifunk")
155 end
156 -- main netconfig
157 main = f:field(Flag, "netconfig", "Netzwerk einrichten", "Setzen Sie den Haken, wenn Sie Ihr Freifunk Netzwerk einrichten wollen.")
158 uci:foreach("wireless", "wifi-device",
159         function(section)
160                 local device = section[".name"]
161                 local dev = f:field(Flag, "device_" .. device , "<b>Drahtloses Netzwerk \"" .. device:upper() .. "\"</b> ", "Konfigurieren Sie Ihre drahtlose " .. device:upper() .. "Schnittstelle (WLAN).")
162                         dev:depends("netconfig", "1")
163                         dev.rmempty = false
164                         function dev.cfgvalue(self, section)
165                                 return uci:get("freifunk", "wizard", "device_" .. device)
166                         end
167                         function dev.write(self, sec, value)
168                                 if value then
169                                         uci:set("freifunk", "wizard", "device_" .. device, value)
170                                         uci:save("freifunk")
171                                 end
172                         end
173                 local chan = f:field(ListValue, "chan_" .. device, device:upper() .. "  Freifunk Kanal einrichten", "Ihr Gerät und benachbarte Freifunk Knoten müssen auf demselben Kanal senden. Je nach Gerätetyp können Sie zwischen verschiedenen 2,4Ghz und 5Ghz Kanälen auswählen.")
174                         chan:depends("device_" .. device, "1")
175                         chan.rmempty = true
176                         function chan.cfgvalue(self, section)
177                                 return uci:get("freifunk", "wizard", "chan_" .. device)
178                         end
179
180                         chan:value('default')
181                         for _, f in ipairs(sys.wifi.channels(device)) do
182                                 if not f.restricted then
183                                         chan:value(f.channel)
184                                 end
185                         end
186
187                         function chan.write(self, sec, value)
188                                 if value then
189                                         uci:set("freifunk", "wizard", "chan_" .. device, value)
190                                         uci:save("freifunk")
191                                 end
192                         end
193
194                         local meship = f:field(Value, "meship_" .. device, device:upper() .. "  Mesh IP Adresse einrichten", "Ihre Mesh IP Adresse erhalten Sie von der Freifunk Gemeinschaft in Ihrer Nachbarschaft. Es ist eine netzweit eindeutige Identifikation, z.B. 104.1.1.1.")
195                         meship:depends("device_" .. device, "1")
196                         meship.rmempty = true
197                         function meship.cfgvalue(self, section)
198                                 return uci:get("freifunk", "wizard", "meship_" .. device)
199                         end
200                         function meship.validate(self, value)
201                                 local x = ip.IPv4(value)
202                                 return ( x and x:prefix() == 32 ) and x:string() or ""
203                         end
204                         function meship.write(self, sec, value)
205                                 uci:set("freifunk", "wizard", "meship_" .. device, value)
206                                 local new_ip = ip.IPv4(value)
207                                 if new_ip then
208                                         local new_hostname = new_ip:string():gsub("%.", "-")
209                                         uci:set("freifunk", "wizard", "hostname", new_hostname)
210                                         uci:save("freifunk")
211                                 end
212                         end
213                 if has_ipv6 then
214                         local meship6 = f:field(Value, "meship6_" .. device, device:upper() .. "  Mesh IPv6 Adresse einrichten", "Ihre Mesh IP Adresse wird automatisch berechnet")
215                         meship6:depends("device_" .. device, "1")
216                         meship6.rmempty = true
217                         function meship6.cfgvalue(self, section)
218                                 return get_ula(get_mac(device))
219                         end
220                 end
221         
222                 local client = f:field(Flag, "client_" .. device, device:upper() .. "  DHCP anbieten", "DHCP weist verbundenen Benutzern automatisch eine Adresse zu. Diese Option sollten Sie unbedingt aktivieren, wenn Sie Nutzer an der drahtlosen Schnittstelle erwarten.")
223                         client:depends("device_" .. device, "1")
224                         client.rmempty = false
225                         function client.cfgvalue(self, section)
226                                 return uci:get("freifunk", "wizard", "client_" .. device)
227                         end
228                         function client.write(self, sec, value)
229                                 uci:set("freifunk", "wizard", "client_" .. device, value)
230                                 uci:save("freifunk")
231                         end
232                 local dhcpmesh = f:field(Value, "dhcpmesh_" .. device, device:upper() .. "  Mesh DHCP anbieten", "Bestimmen Sie den Adressbereich aus dem Ihre Nutzer IP Adressen erhalten. Es wird empfohlen einen Adressbereich aus Ihrer lokalen Freifunk Gemeinschaft zu nutzen. Der Adressbereich ist ein netzweit eindeutiger Netzbereich. z.B. 104.1.2.1/28")
233                         dhcpmesh:depends("client_" .. device, "1")
234                         dhcpmesh.rmempty = true
235                         function dhcpmesh.cfgvalue(self, section)
236                                 return uci:get("freifunk", "wizard", "dhcpmesh_" .. device)
237                         end
238                         function dhcpmesh.validate(self, value)
239                                 local x = ip.IPv4(value)
240                                 return ( x and x:minhost()) and x:string() or ""
241                         end
242                         function dhcpmesh.write(self, sec, value)
243                                 uci:set("freifunk", "wizard", "dhcpmesh_" .. device, value)
244                                 uci:save("freifunk")
245                         end
246                 local hwtype = section.type
247                 if hwtype == "atheros" then
248                         local vap = f:field(Flag, "vap_" .. device , "Virtueller Drahtloser Zugangspunkt", "Konfigurieren Sie Ihren Virtuellen AP")
249                         vap:depends("client_" .. device, "1")
250                         vap.rmempty = false
251                         function vap.cfgvalue(self, section)
252                                 return uci:get("freifunk", "wizard", "vap_" .. device)
253                         end
254                         function vap.write(self, sec, value)
255                                 uci:set("freifunk", "wizard", "vap_" .. device, value)
256                                 uci:save("freifunk")
257                         end
258                 end
259         end)
260
261 uci:foreach("network", "interface",
262         function(section)
263                 local device = section[".name"]
264                 local ifname = uci_state:get("network",device,"ifname")
265                 if device ~= "loopback" and not string.find(device, "gvpn")  and not string.find(device, "wifi") and not string.find(device, "wl") and not string.find(device, "wlan") and not string.find(device, "wireless") and not string.find(device, "radio") then
266                         dev = f:field(Flag, "device_" .. device , "<b>Drahtgebundenes Netzwerk \"" .. device:upper() .. "\"</b>", "Konfigurieren Sie Ihre drahtgebunde " .. device:upper() .. " Schnittstelle (LAN).")
267                                 dev:depends("netconfig", "1")
268                                 dev.rmempty = false
269                                 function dev.cfgvalue(self, section)
270                                         return uci:get("freifunk", "wizard", "device_" .. device)
271                                 end
272                                 function dev.write(self, sec, value)
273                                         uci:set("freifunk", "wizard", "device_" .. device, value)
274                                         uci:save("freifunk")
275                                 end
276                         meship = f:field(Value, "meship_" .. device, device:upper() .. "  Mesh IP Adresse einrichten", "Ihre Mesh IP Adresse erhalten Sie von der Freifunk Gemeinschaft in Ihrer Nachbarschaft. Es ist eine netzweit eindeutige Identifikation, z.B. 104.1.1.1.")
277                                 meship:depends("device_" .. device, "1")
278                                 meship.rmempty = true
279                                 function meship.cfgvalue(self, section)
280                                         return uci:get("freifunk", "wizard", "meship_" .. device)
281                                 end
282                                 function meship.validate(self, value)
283                                         local x = ip.IPv4(value)
284                                         return ( x and x:prefix() == 32 ) and x:string() or ""
285                                 end
286                                 function meship.write(self, sec, value)
287                                         uci:set("freifunk", "wizard", "meship_" .. device, value)
288                                 end
289                         if has_ipv6 then
290                                 meship6 = f:field(Value, "meship6_" .. device, device:upper() .. "  Mesh IPv6 Adresse einrichten", "Ihre Mesh IP Adresse wird automatisch berechnet")
291                                 meship6:depends("device_" .. device, "1")
292                                 meship6.rmempty = true
293                                 function meship6.cfgvalue(self, section)
294                                         return get_ula(get_mac(ifname))
295                                 end
296                         end
297
298                         client = f:field(Flag, "client_" .. device, device:upper() .. "  DHCP anbieten","DHCP weist verbundenen Benutzern automatisch eine Adresse zu. Diese Option sollten Sie unbedingt aktivieren, wenn Sie Nutzer an der drahtlosen Schnittstelle erwarten.")
299                                 client:depends("device_" .. device, "1")
300                                 client.rmempty = false
301                                 function client.cfgvalue(self, section)
302                                         return uci:get("freifunk", "wizard", "client_" .. device)
303                                 end
304                                 function client.write(self, sec, value)
305                                         uci:set("freifunk", "wizard", "client_" .. device, value)
306                                         uci:save("freifunk")
307                                 end
308                         dhcpmesh = f:field(Value, "dhcpmesh_" .. device, device:upper() .. "  Mesh DHCP anbieten ", "Bestimmen Sie den Adressbereich aus dem Ihre Nutzer IP Adressen erhalten. Es wird empfohlen einen Adressbereich aus Ihrer lokalen Freifunk Gemeinschaft zu nutzen. Der Adressbereich ist ein netzweit eindeutiger Netzbereich. z.B. 104.1.2.1/28")
309                                 dhcpmesh:depends("client_" .. device, "1")
310                                 dhcpmesh.rmempty = true
311                                 function dhcpmesh.cfgvalue(self, section)
312                                         return uci:get("freifunk", "wizard", "dhcpmesh_" .. device)
313                                 end
314                                 function dhcpmesh.validate(self, value)
315                                         local x = ip.IPv4(value)
316                                         return ( x and x:prefix() <= 30 and x:minhost()) and x:string() or ""
317                                 end
318                                 function dhcpmesh.write(self, sec, value)
319                                         uci:set("freifunk", "wizard", "dhcpmesh_" .. device, value)
320                                         uci:save("freifunk")
321                                 end
322                 end
323         end)
324
325
326 local syslat = uci:get("freifunk", "wizard", "latitude") or 52
327 local syslon = uci:get("freifunk", "wizard", "longitude") or 10
328 uci:foreach("system", "system", function(s)
329                 if s.latitude then
330                         syslat = s.latitude
331                 end
332                 if s.longitude then
333                         syslon = s.longitude
334                 end
335 end)
336 uci:foreach("olsrd", "LoadPlugin", function(s)
337         if s.library == "olsrd_nameservice.so.0.3" then
338                 if s.lat then
339                         syslat = s.lat
340                 end
341                 if s.lon then
342                         syslon = s.lon
343                 end
344         end
345 end)
346
347 lat = f:field(Value, "lat", "geographischer Breitengrad", "Setzen Sie den Breitengrad (Latitude) Ihres Geräts.")
348 lat:depends("netconfig", "1")
349 function lat.cfgvalue(self, section)
350         return syslat
351 end
352 function lat.write(self, section, value)
353         uci:set("freifunk", "wizard", "latitude", value)
354         uci:save("freifunk")
355 end
356
357 lon = f:field(Value, "lon", "geograpischer Längengrad", "Setzen Sie den Längengrad (Longitude) Ihres Geräts.")
358 lon:depends("netconfig", "1")
359 function lon.cfgvalue(self, section)
360         return syslon
361 end
362 function lon.write(self, section, value)
363         uci:set("freifunk", "wizard", "longitude", value)
364         uci:save("freifunk")
365 end
366
367 --[[
368 *Opens an OpenStreetMap iframe or popup
369 *Makes use of resources/OSMLatLon.htm and htdocs/resources/osm.js
370 (is that the right place for files like these?)
371 ]]--
372
373 local class = util.class
374
375 OpenStreetMapLonLat = class(AbstractValue)
376
377 function OpenStreetMapLonLat.__init__(self, ...)
378         AbstractValue.__init__(self, ...)
379         self.template = "cbi/osmll_value"
380         self.latfield = nil
381         self.lonfield = nil
382         self.centerlat = ""
383         self.centerlon = ""
384         self.zoom = "0"
385         self.width = "100%" --popups will ignore the %-symbol, "100%" is interpreted as "100"
386         self.height = "600"
387         self.popup = false
388         self.displaytext="OpenStreetMap" --text on button, that loads and displays the OSMap
389         self.hidetext="X" -- text on button, that hides OSMap
390 end
391
392 osm = f:field(OpenStreetMapLonLat, "latlon", "Geokoordinaten mit OpenStreetMap ermitteln:", "Klicken Sie auf Ihren Standort in der Karte. Diese Karte funktioniert nur, wenn das Gerät bereits eine Verbindung zum Internet hat.")
393 osm:depends("netconfig", "1")
394 osm.latfield = "lat"
395 osm.lonfield = "lon"
396 osm.centerlat = syslat
397 osm.centerlon = syslon
398 osm.width = "100%"
399 osm.height = "600"
400 osm.popup = false
401 syslatlengh = string.len(syslat)
402 if syslatlengh > 7 then
403         osm.zoom = "15"
404 elseif syslatlengh > 5 then
405         osm.zoom = "12"
406 else
407         osm.zoom = "6"
408 end
409 osm.displaytext="OpenStreetMap anzeigen"
410 osm.hidetext="OpenStreetMap verbergen"
411
412 share = f:field(Flag, "sharenet", "Eigenen Internetzugang freigeben", "Geben Sie Ihren Internetzugang im Freifunknetz frei.")
413 share.rmempty = false
414 share:depends("netconfig", "1")
415 function share.cfgvalue(self, section)
416         return uci:get("freifunk", "wizard", "share")
417 end
418 function share.write(self, section, value)
419         uci:set("freifunk", "wizard", "share", value)
420         uci:save("freifunk")
421 end
422
423 wanproto = f:field(ListValue, "wanproto", "Protokoll des Internetzugangs", "Geben Sie das Protokol an ueber das eine Internet verbindung hergestellt werden kann.")
424 wanproto:depends("sharenet", "1")
425 wanproto:value("static", translate("manual", "manual"))
426 wanproto:value("dhcp", translate("automatic", "automatic"))
427 if has_pppoe then wanproto:value("pppoe", "PPPoE") end
428 if has_pptp  then wanproto:value("pptp",  "PPTP")  end
429 function wanproto.cfgvalue(self, section)
430         return uci:get("network", "wan", "proto") or "dhcp"
431 end
432 function wanproto.write(self, section, value)
433         uci:set("network", "wan", "proto", value)
434         uci:save("network")
435 end
436 wanip = f:field(Value, "wanipaddr", translate("ipaddress"))
437 wanip:depends("wanproto", "static")
438 function wanip.cfgvalue(self, section)
439         return uci:get("network", "wan", "ipaddr")
440 end
441 function wanip.write(self, section, value)
442         uci:set("network", "wan", "ipaddr", value)
443         uci:save("network")
444 end
445 wannm = f:field(Value, "wannetmask", translate("netmask"))
446 wannm:depends("wanproto", "static")
447 function wannm.cfgvalue(self, section)
448         return uci:get("network", "wan", "netmask")
449 end
450 function wannm.write(self, section, value)
451         uci:set("network", "wan", "netmask", value)
452         uci:save("network")
453 end
454 wangw = f:field(Value, "wangateway", translate("gateway"))
455 wangw:depends("wanproto", "static")
456 wangw.rmempty = true
457 function wangw.cfgvalue(self, section)
458         return uci:get("network", "wan", "gateway")
459 end
460 function wangw.write(self, section, value)
461         uci:set("network", "wan", "gateway", value)
462         uci:save("network")
463 end
464 wandns = f:field(Value, "wandns", translate("dnsserver"))
465 wandns:depends("wanproto", "static")
466 wandns.rmempty = true
467 function wandns.cfgvalue(self, section)
468         return uci:get("network", "wan", "dns")
469 end
470 function wandns.write(self, section, value)
471         uci:set("network", "wan", "dns", value)
472         uci:save("network")
473 end
474 wanusr = f:field(Value, "wanusername", translate("username"))
475 wanusr:depends("wanproto", "pppoe")
476 wanusr:depends("wanproto", "pptp")
477 function wanusr.cfgvalue(self, section)
478         return uci:get("network", "wan", "username")
479 end
480 function wanusr.write(self, section, value)
481         uci:set("network", "wan", "username", value)
482         uci:save("network")
483 end
484 wanpwd = f:field(Value, "wanpassword", translate("password"))
485 wanpwd.password = true
486 wanpwd:depends("wanproto", "pppoe")
487 wanpwd:depends("wanproto", "pptp")
488 function wanpwd.cfgvalue(self, section)
489         return uci:get("network", "wan", "password")
490 end
491 function wanpwd.write(self, section, value)
492         uci:set("network", "wan", "password", value)
493         uci:save("network")
494 end
495
496 wansec = f:field(Flag, "wansec", "WAN-Zugriff auf Gateway beschränken", "Verbieten Sie Zugriffe auf Ihr lokales Netzwerk aus dem Freifunknetz.")
497 wansec.rmempty = false
498 wansec:depends("wanproto", "static")
499 wansec:depends("wanproto", "dhcp")
500 function wansec.cfgvalue(self, section)
501         return uci:get("freifunk", "wizard", "wan_security")
502 end
503 function wansec.write(self, section, value)
504         uci:set("freifunk", "wizard", "wan_security", value)
505         uci:save("freifunk")
506 end
507 if has_qos then
508         wanqosdown = f:field(Value, "wanqosdown", "Download Bandbreite begrenzen", "kb/s")
509         wanqosdown:depends("sharenet", "1")
510         function wanqosdown.cfgvalue(self, section)
511                 return uci:get("qos", "wan", "download")
512         end
513         function wanqosdown.write(self, section, value)
514                 uci:set("qos", "wan", "download", value)
515                 uci:save("qos")
516         end
517         wanqosup = f:field(Value, "wanqosup", "Upload Bandbreite begrenzen", "kb/s")
518         wanqosup:depends("sharenet", "1")
519         function wanqosup.cfgvalue(self, section)
520                 return uci:get("qos", "wan", "upload")
521         end
522         function wanqosup.write(self, section, value)
523                 uci:set("qos", "wan", "upload", value)
524                 uci:save("qos")
525         end
526 end
527
528 if has_l2gvpn then
529         gvpn = f:field(Flag, "gvpn", "Freifunk Internet Tunnel", "Verbinden Sie ihren Router ueber das Internet mit anderen Freifunknetzen.")
530         gvpn.rmempty = false
531         gvpn:depends("sharenet", "1")
532         function gvpn.cfgvalue(self, section)
533                 return uci:get("freifunk", "wizard", "gvpn")
534         end
535         function gvpn.write(self, section, value)
536                 uci:set("freifunk", "wizard", "gvpn", value)
537                 uci:save("freifunk")
538         end
539         gvpnip = f:field(Value, "gvpnipaddr", translate("ipaddress"))
540         gvpnip:depends("gvpn", "1")
541         function gvpnip.cfgvalue(self, section)
542                 return uci:get("l2gvpn", "bbb", "ip") or uci:get("network", "gvpn", "ipaddr")
543         end
544         function gvpnip.validate(self, value)
545                 local x = ip.IPv4(value)
546                 return ( x and x:prefix() == 32 ) and x:string() or ""
547         end
548 end
549
550 if has_hb then
551         hb = f:field(Flag, "hb", "Heartbeat aktivieren","Dem Gerät erlauben anonyme Statistiken zu übertragen. (empfohlen)")
552         hb.rmempty = false
553         hb:depends("netconfig", "1")
554         function hb.cfgvalue(self, section)
555                 return uci:get("freifunk", "wizard", "hb")
556         end
557         function hb.write(self, section, value)
558                 uci:set("freifunk", "wizard", "hb", value)
559                 uci:save("freifunk")
560         end
561 end
562
563 -------------------- Control --------------------
564 function f.handle(self, state, data)
565         if state == FORM_VALID then
566                 local debug = uci:get("freifunk", "wizard", "debug")
567                 if debug == "1" then
568                         if data.pw1 then
569                                 local stat = luci.sys.user.setpasswd("root", data.pw1) == 0
570                                 if stat then
571                                         f.message = translate("a_s_changepw_changed")
572                                 else
573                                         f.errmessage = translate("unknownerror")
574                                 end
575                         end
576                         data.pw1 = nil
577                         data.pw2 = nil
578                         luci.http.redirect(luci.dispatcher.build_url(unpack(luci.dispatcher.context.requested.path), "system", "system"))
579                 else
580                         if data.pw1 then
581                                 local stat = luci.sys.user.setpasswd("root", data.pw1) == 0
582                         end
583                         data.pw1 = nil
584                         data.pw2 = nil
585                         uci:commit("freifunk")
586                         uci:commit("wireless")
587                         uci:commit("network")
588                         uci:commit("dhcp")
589                         uci:commit("luci_splash")
590                         uci:commit("firewall")
591                         uci:commit("system")
592                         uci:commit("uhttpd")
593                         uci:commit("olsrd")
594                         uci:commit("manager")
595                         if has_autoipv6 then
596                                 uci:commit("autoipv6")
597                         end
598                         if has_qos then
599                                 uci:commit("qos")
600                         end
601                         if has_l2gvpn then
602                                 uci:commit("l2gvpn")
603                         end
604                         if has_radvd then
605                                 uci:commit("radvd")
606                         end
607 -- the following line didn't work without admin-mini, for now i just replaced it with sys.exec... soma
608 --                      luci.http.redirect(luci.dispatcher.build_url(unpack(luci.dispatcher.context.requested.path), "system", "reboot") .. "?reboot=1")
609                         sys.exec("reboot")
610                 end
611                 return false
612         elseif state == FORM_INVALID then
613                 self.errmessage = "Ungültige Eingabe: Bitte die Formularfelder auf Fehler prüfen."
614         end
615         return true
616 end
617
618 local function _strip_internals(tbl)
619         tbl = tbl or {}
620         for k, v in pairs(tbl) do
621                 if k:sub(1, 1) == "." then
622                         tbl[k] = nil
623                 end
624         end
625         return tbl
626 end
627 -- Configure Freifunk checked
628 function main.write(self, section, value)
629         if value == "0" then
630                 uci:set("freifunk", "wizard", "netconfig", "0")
631                 uci:save("freifunk")
632                 return
633         end
634         -- Collect IP-Address
635         local community = net:formvalue(section)
636         suffix = uci:get("freifunk", community, "suffix") or "olsr"
637
638         -- Invalidate fields
639         if not community then
640                 net.tag_missing[section] = true
641                 return
642         end
643
644         uci:set("freifunk", "wizard", "netconfig", "1")
645         uci:save("freifunk")
646
647         local external
648         external = uci:get("freifunk", community, "external") or ""
649
650         local netname = "wireless"
651         local network
652         network = ip.IPv4(uci:get("freifunk", community, "mesh_network") or "104.0.0.0/8")
653
654         -- Tune community settings
655         if community and uci:get("freifunk", community) then
656                 uci:tset("freifunk", "community", uci:get_all("freifunk", community))
657         end
658
659         -- Cleanup
660         uci:delete_all("firewall","zone", {name="freifunk"})
661         uci:delete_all("firewall","forwarding", {dest="freifunk"})
662         uci:delete_all("firewall","forwarding", {src="freifunk"})
663         uci:delete_all("firewall","rule", {dest="freifunk"})
664         uci:delete_all("firewall","rule", {src="freifunk"})
665         uci:save("firewall")
666         -- Create firewall zone and add default rules (first time)
667         --                    firewall_create_zone("name"    , "input" , "output", "forward ", Masqurade)
668         local newzone = tools.firewall_create_zone("freifunk", "ACCEPT", "ACCEPT", "REJECT"  , true)
669         if newzone then
670                 uci:foreach("freifunk", "fw_forwarding", function(section)
671                         uci:section("firewall", "forwarding", nil, section)
672                 end)
673                 uci:foreach(external, "fw_forwarding", function(section)
674                         uci:section("firewall", "forwarding", nil, section)
675                 end)
676
677                 uci:foreach("freifunk", "fw_rule", function(section)
678                         uci:section("firewall", "rule", nil, section)
679                 end)
680                 uci:foreach(external, "fw_rule", function(section)
681                         uci:section("firewall", "rule", nil, section)
682                 end)
683         end
684         uci:save("firewall")
685         if has_hb then
686                 uci:delete("manager", "heartbeat", "interface")
687                 uci:save("manager")
688         end
689         -- Delete olsrdv4
690         uci:delete_all("olsrd", "olsrd")
691         local olsrbase
692         olsrbase = uci:get_all("freifunk", "olsrd") or {}
693         util.update(olsrbase, uci:get_all(external, "olsrd") or {})
694         if has_ipv6 then
695                 olsrbase.IpVersion='6and4'
696         else
697                 olsrbase.IpVersion='4'
698         end
699         uci:section("olsrd", "olsrd", nil, olsrbase)
700         -- Delete olsrdv4 old p2pd settings
701         uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_mdns.so.1.0.0"})
702         uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_p2pd.so.0.1.0"})
703         -- Write olsrdv4 new p2pd settings
704         uci:section("olsrd", "LoadPlugin", nil, {
705                 library     = "olsrd_p2pd.so.0.1.0",
706                 P2pdTtl     = 10,
707                 UdpDestPort = "224.0.0.251 5353",
708                 ignore      = 1,
709         })
710         -- Delete http plugin
711         uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_httpinfo.so.0.1"})
712
713         -- Delete olsrdv4 old interface
714         uci:delete_all("olsrd", "Interface")
715         uci:delete_all("olsrd", "Hna4")
716         -- Create wireless ip4/ip6 and firewall config
717         uci:foreach("wireless", "wifi-device",
718         function(sec)
719                 local device = sec[".name"]
720                 if not luci.http.formvalue("cbid.ffwizward.1.device_" .. device) then
721                         return
722                 end
723                 node_ip = luci.http.formvalue("cbid.ffwizward.1.meship_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.meship_" .. device))
724                 if has_ipv6 then
725                         node_ip6 = luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device) and ip.IPv6(luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device))
726                 end
727                 if not node_ip or not network or not network:contains(node_ip) then
728                         meship.tag_missing[section] = true
729                         node_ip = nil
730                         return
731                 end
732                 -- rename the wireless interface s/wifi/wireless/
733                 local nif
734                 if string.find(device, "wifi") then
735                         nif = string.gsub(device,"wifi", netname)
736                 elseif string.find(device, "wl") then
737                         nif = string.gsub(device,"wl", netname)
738                 elseif string.find(device, "wlan") then
739                         nif = string.gsub(device,"wlan", netname)
740                 elseif string.find(device, "radio") then
741                         nif = string.gsub(device,"radio", netname)
742                 end
743                 -- Cleanup
744                 tools.wifi_delete_ifaces(device)
745                 -- tools.network_remove_interface(device)
746                 uci:delete("network", device .. "dhcp")
747                 uci:delete("network", device)
748                 tools.firewall_zone_remove_interface("freifunk", device)
749                 -- tools.network_remove_interface(nif)
750                 uci:delete("network", nif .. "dhcp")
751                 uci:delete("network", nif)
752                 tools.firewall_zone_remove_interface("freifunk", nif)
753                 -- Delete old dhcp
754                 uci:delete("dhcp", device)
755                 uci:delete("dhcp", device .. "dhcp")
756                 uci:delete("dhcp", nif)
757                 uci:delete("dhcp", nif .. "dhcp")
758                 -- Delete old splash
759                 uci:delete_all("luci_splash", "iface", {network=device.."dhcp", zone="freifunk"})
760                 uci:delete_all("luci_splash", "iface", {network=nif.."dhcp", zone="freifunk"})
761                 -- Delete old radvd
762                 if has_radvd then
763                         uci:delete_all("radvd", "interface", {interface=nif.."dhcp"})
764                         uci:delete_all("radvd", "interface", {interface=nif})
765                         uci:delete_all("radvd", "prefix", {interface=nif.."dhcp"})
766                         uci:delete_all("radvd", "prefix", {interface=nif})
767                 end
768                 -- New Config
769                 -- Tune wifi device
770                 local ssid = uci:get("freifunk", community, "ssid") or "olsr.freifunk.net"
771                 local devconfig = uci:get_all("freifunk", "wifi_device")
772                 util.update(devconfig, uci:get_all(external, "wifi_device") or {})
773                 local channel = luci.http.formvalue("cbid.ffwizward.1.chan_" .. device)
774                 local hwmode = "11bg"
775                 local bssid = uci:get_all(external, "wifi_iface", "bssid") or "02:CA:FF:EE:BA:BE"
776                 local mrate = 5500
777                 -- set bssid, see https://kifuse02.pberg.freifunk.net/moin/channel-bssid-essid for schema
778                 if channel and channel ~= "default" then
779                         if devconfig.channel ~= channel then
780                                 devconfig.channel = channel
781                                 local chan = tonumber(channel)
782                                 if chan >= 0 and chan < 10 then
783                                         bssid = channel .. "2:CA:FF:EE:BA:BE"
784                                 elseif chan == 10 then 
785                                         bssid = "02:CA:FF:EE:BA:BE" 
786                                 elseif chan >= 11 and chan <= 14 then
787                                         bssid = string.format("%X",channel) .. "2:CA:FF:EE:BA:BE"
788                                 elseif chan >= 36 and chan <= 64 then
789                                         hwmode = "11a"
790                                         mrate = ""
791                                         outdoor = 0
792                                         bssid = "00:" .. channel ..":CA:FF:EE:EE"
793                                 elseif chan >= 100 and chan <= 140 then
794                                         hwmode = "11a"
795                                         mrate = ""
796                                         outdoor = 1
797                                         bssid = "01:" .. string.sub(channel, 2) .. ":CA:FF:EE:EE"
798                                 end
799                                 devconfig.hwmode = hwmode
800                                 devconfig.outdoor = outdoor
801                         end
802                         ssid = ssid .. " - ch" .. channel
803                 end
804                 uci:tset("wireless", device, devconfig)
805                 -- Create wifi iface
806                 local ifconfig = uci:get_all("freifunk", "wifi_iface")
807                 util.update(ifconfig, uci:get_all(external, "wifi_iface") or {})
808                 ifconfig.device = device
809                 ifconfig.network = nif
810                 ifconfig.ssid = ssid
811                 ifconfig.bssid = bssid
812                 ifconfig.encryption="none"
813                 -- Read Preset 
814                 local netconfig = uci:get_all("freifunk", "interface")
815                 util.update(netconfig, uci:get_all(external, "interface") or {})
816                 netconfig.proto = "static"
817                 netconfig.ipaddr = node_ip:string()
818                 if has_ipv6 then
819                         netconfig.ip6addr = node_ip6:string()
820                 end
821                 uci:section("network", "interface", nif, netconfig)
822                 if has_radvd then
823                         uci:section("radvd", "interface", nil, {
824                                 interface          =nif,
825                                 AdvSendAdvert      =1,
826                                 AdvManagedFlag     =0,
827                                 AdvOtherConfigFlag =0,
828                                 ignore             =0
829                         })
830                         uci:section("radvd", "prefix", nil, {
831                                 interface          =nif,
832                                 AdvOnLink          =1,
833                                 AdvAutonomous      =1,
834                                 AdvRouterAddr      =0,
835                                 ignore             =0,
836                         })
837                         uci:save("radvd")
838                 end
839                 local new_hostname = node_ip:string():gsub("%.", "-")
840                 uci:set("freifunk", "wizard", "hostname", new_hostname)
841                 uci:save("freifunk")
842                 tools.firewall_zone_add_interface("freifunk", nif)
843                 uci:save("firewall")
844                 -- Write new olsrv4 interface
845                 local olsrifbase = uci:get_all("freifunk", "olsr_interface")
846                 util.update(olsrifbase, uci:get_all(external, "olsr_interface") or {})
847                 olsrifbase.interface = nif
848                 olsrifbase.ignore    = "0"
849                 uci:section("olsrd", "Interface", nil, olsrifbase)
850                 -- Collect MESH DHCP IP NET
851                 local client = luci.http.formvalue("cbid.ffwizward.1.client_" .. device)
852                 if client then
853                         local dhcpmeshnet = luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device))
854                         if has_hb then
855                                 local ifacelist = uci:get_list("manager", "heartbeat", "interface") or {}
856                                 table.insert(ifacelist,nif .. "dhcp")
857                                 uci:set_list("manager", "heartbeat", "interface", ifacelist)
858                                 uci:save("manager")
859                         end
860                         if dhcpmeshnet then
861                                 if not dhcpmeshnet:minhost() or not dhcpmeshnet:mask() then
862                                         dhcpmesh.tag_missing[section] = true
863                                         dhcpmeshnet = nil
864                                         return
865                                 end
866                                 dhcp_ip = dhcpmeshnet:minhost():string()
867                                 dhcp_mask = dhcpmeshnet:mask():string()
868                                 dhcp_network = dhcpmeshnet:network():string()
869                                 uci:section("olsrd", "Hna4", nil, {
870                                         netmask  = dhcp_mask,
871                                         netaddr  = dhcp_network
872                                 })
873                                 uci:foreach("olsrd", "LoadPlugin",
874                                         function(s)             
875                                                 if s.library == "olsrd_p2pd.so.0.1.0" then
876                                                         uci:set("olsrd", s['.name'], "ignore", "0")
877                                                         local nonolsr = uci:get("olsrd", s['.name'], "NonOlsrIf") or ""
878                                                         vap = luci.http.formvalue("cbid.ffwizward.1.vap_" .. device)
879                                                         if vap then
880                                                                 nonolsr = nif.."dhcp "..nonolsr
881                                                         else
882                                                                 nonolsr = nif.." "..nonolsr
883                                                         end
884                                                         uci:set("olsrd", s['.name'], "NonOlsrIf", nonolsr)
885                                                 end
886                                         end)
887                         else
888                                 local subnet_prefix = tonumber(uci:get("freifunk", community, "splash_prefix")) or 27
889                                 local pool_network = uci:get("freifunk", community, "splash_network") or "10.104.0.0/16"
890                                 local pool = luci.ip.IPv4(pool_network)
891                                 local ip = tostring(node_ip)
892                                 if pool and ip then
893                                         local hosts_per_subnet = 2^(32 - subnet_prefix)
894                                         local number_of_subnets = (2^pool:prefix())/hosts_per_subnet
895                                         local seed1, seed2 = ip:match("(%d+)%.(%d+)$")
896                                         if seed1 and seed2 then
897                                                 math.randomseed(seed1 * seed2)
898                                         end
899                                         local subnet = pool:add(hosts_per_subnet * math.random(number_of_subnets))
900                                         dhcp_ip = subnet:network(subnet_prefix):add(1):string()
901                                         dhcp_mask = subnet:mask(subnet_prefix):string()
902                                 end
903                         end
904                         if dhcp_ip and dhcp_mask then
905                                 -- Create alias
906                                 local aliasbase = uci:get_all("freifunk", "alias")
907                                 util.update(aliasbase, uci:get_all(external, "alias") or {})
908                                 aliasbase.ipaddr = dhcp_ip
909                                 aliasbase.netmask = dhcp_mask
910                                 aliasbase.proto = "static"
911                                 vap = luci.http.formvalue("cbid.ffwizward.1.vap_" .. device)
912                                 if vap then
913                                         uci:section("network", "interface", nif .. "dhcp", aliasbase)
914                                         uci:section("wireless", "wifi-iface", nil, {
915                                                 device     =device,
916                                                 mode       ="ap",
917                                                 encryption ="none",
918                                                 network    =nif .. "dhcp",
919                                                 ssid       ="AP-" .. ssid
920                                         })
921                                         if has_radvd then
922                                                 uci:section("radvd", "interface", nil, {
923                                                         interface          =nif .. "dhcp",
924                                                         AdvSendAdvert      =1,
925                                                         AdvManagedFlag     =0,
926                                                         AdvOtherConfigFlag =0,
927                                                         ignore             =0
928                                                 })
929                                                 uci:section("radvd", "prefix", nil, {
930                                                         interface          =nif .. "dhcp",
931                                                         AdvOnLink          =1,
932                                                         AdvAutonomous      =1,
933                                                         AdvRouterAddr      =0,
934                                                         ignore             =0
935                                                 })
936                                                 uci:save("radvd")
937                                         end
938                                         tools.firewall_zone_add_interface("freifunk", nif .. "dhcp")
939                                         uci:save("wireless")
940                                         ifconfig.mcast_rate = nil
941                                         ifconfig.encryption="none"
942                                 else
943                                         aliasbase.interface = nif
944                                         uci:section("network", "alias", nif .. "dhcp", aliasbase)
945                                 end
946                                 -- Create dhcp
947                                 local dhcpbase = uci:get_all("freifunk", "dhcp")
948                                 util.update(dhcpbase, uci:get_all(external, "dhcp") or {})
949                                 dhcpbase.interface = nif .. "dhcp"
950                                 dhcpbase.force = 1
951                                 uci:section("dhcp", "dhcp", nif .. "dhcp", dhcpbase)
952                                 uci:set_list("dhcp", nif .. "dhcp", "dhcp_option", "119,olsr")
953                                 -- Create firewall settings
954                                 uci:delete_all("firewall", "rule", {
955                                         src="freifunk",
956                                         proto="udp",
957                                         dest_port="53"
958                                 })
959                                 uci:section("firewall", "rule", nil, {
960                                         src="freifunk",
961                                         proto="udp",
962                                         dest_port="53",
963                                         target="ACCEPT"
964                                 })
965                                 uci:delete_all("firewall", "rule", {
966                                         src="freifunk",
967                                         proto="udp",
968                                         src_port="68",
969                                         dest_port="67"
970                                 })
971                                 uci:section("firewall", "rule", nil, {
972                                         src="freifunk",
973                                         proto="udp",
974                                         src_port="68",
975                                         dest_port="67",
976                                         target="ACCEPT"
977                                 })
978                                 uci:delete_all("firewall", "rule", {
979                                         src="freifunk",
980                                         proto="tcp",
981                                         dest_port="8082",
982                                 })
983                                 uci:section("firewall", "rule", nil, {
984                                         src="freifunk",
985                                         proto="tcp",
986                                         dest_port="8082",
987                                         target="ACCEPT"
988                                 })
989                                 -- Register splash
990                                 uci:section("luci_splash", "iface", nil, {network=nif.."dhcp", zone="freifunk"})
991                                 uci:save("luci_splash")
992                                 -- Make sure that luci_splash is enabled
993                                 sys.init.enable("luci_splash")
994                         end
995                 else
996                         -- Delete old splash
997                         uci:delete_all("luci_splash", "iface", {network=device.."dhcp", zone="freifunk"})
998                 end
999                 --Write Ad-Hoc wifi section after AP wifi section
1000                 uci:section("wireless", "wifi-iface", nil, ifconfig)
1001                 uci:save("network")
1002                 uci:save("wireless")
1003                 uci:save("network")
1004                 uci:save("firewall")
1005                 uci:save("dhcp")
1006         end)
1007         -- Create wired ip and firewall config
1008         uci:foreach("network", "interface",
1009                 function(sec)
1010                 local device = sec[".name"]
1011                 if not luci.http.formvalue("cbid.ffwizward.1.device_" .. device) then
1012                         return
1013                 end
1014                 if device ~= "loopback" and not string.find(device, "wifi") and not string.find(device, "wl") and not string.find(device, "wlan") and not string.find(device, "wireless") and not string.find(device, "radio") then
1015                         local node_ip
1016                         node_ip = luci.http.formvalue("cbid.ffwizward.1.meship_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.meship_" .. device))
1017                         if has_ipv6 then
1018                                 node_ip6 = luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device) and ip.IPv6(luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device))
1019                         end
1020                         if not node_ip or not network or not network:contains(node_ip) then
1021                                 meship.tag_missing[section] = true
1022                                 node_ip = nil
1023                                 return
1024                         end
1025                         -- Cleanup
1026                         tools.firewall_zone_remove_interface(device, device)
1027                         uci:delete_all("firewall","zone", {name=device})
1028                         uci:delete_all("firewall","forwarding", {src=device})
1029                         uci:delete_all("firewall","forwarding", {dest=device})
1030                         uci:delete("network", device .. "dhcp")
1031                         -- Delete old dhcp
1032                         uci:delete("dhcp", device)
1033                         uci:delete("dhcp", device .. "dhcp")
1034                         -- Delete old splash
1035                         uci:delete_all("luci_splash", "iface", {network=device.."dhcp", zone="freifunk"})
1036                         if has_radvd then
1037                                 uci:delete_all("radvd", "interface", {interface=device.."dhcp"})
1038                                 uci:delete_all("radvd", "interface", {interface=device})
1039                                 uci:delete_all("radvd", "prefix", {interface=device.."dhcp"})
1040                                 uci:delete_all("radvd", "prefix", {interface=device})
1041                         end
1042                         -- New Config
1043                         local netconfig = uci:get_all("freifunk", "interface")
1044                         util.update(netconfig, uci:get_all(external, "interface") or {})
1045                         netconfig.proto = "static"
1046                         netconfig.ipaddr = node_ip:string()
1047                         if has_ipv6 then
1048                                 netconfig.ip6addr = node_ip6:string()
1049                         end
1050                         uci:section("network", "interface", device, netconfig)
1051                         uci:save("network")
1052                         if has_radvd then
1053                                 uci:section("radvd", "interface", nil, {
1054                                         interface          =device,
1055                                         AdvSendAdvert      =1,
1056                                         AdvManagedFlag     =0,
1057                                         AdvOtherConfigFlag =0,
1058                                         ignore             =0
1059                                 })
1060                                 uci:section("radvd", "prefix", nil, {
1061                                         interface          =device,
1062                                         AdvOnLink          =1,
1063                                         AdvAutonomous      =1,
1064                                         AdvRouterAddr      =0,
1065                                         ignore             =0,
1066                                 })
1067                                 uci:save("radvd")
1068                         end
1069                         local new_hostname = node_ip:string():gsub("%.", "-")
1070                         uci:set("freifunk", "wizard", "hostname", new_hostname)
1071                         uci:save("freifunk")
1072                         tools.firewall_zone_add_interface("freifunk", device)
1073                         uci:save("firewall")
1074                         -- Write new olsrv4 interface
1075                         local olsrifbase = uci:get_all("freifunk", "olsr_interface")
1076                         util.update(olsrifbase, uci:get_all(external, "olsr_interface") or {})
1077                         olsrifbase.interface = device
1078                         olsrifbase.ignore    = "0"
1079                         uci:section("olsrd", "Interface", nil, olsrifbase)
1080                         olsrifbase.Mode = 'ether'
1081                         -- Collect MESH DHCP IP NET
1082                         local client = luci.http.formvalue("cbid.ffwizward.1.client_" .. device)
1083                         if client then
1084                                 local dhcpmeshnet = luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device))
1085                                 if has_hb then
1086                                         local ifacelist = uci:get_list("manager", "heartbeat", "interface") or {}
1087                                         table.insert(ifacelist,device .. "dhcp")
1088                                         uci:set_list("manager", "heartbeat", "interface", ifacelist)
1089                                         uci:save("manager")
1090                                 end
1091                                 if dhcpmeshnet then
1092                                         if not dhcpmeshnet:minhost() or not dhcpmeshnet:mask() then
1093                                                 dhcpmesh.tag_missing[section] = true
1094                                                 dhcpmeshnet = nil
1095                                                 return
1096                                         end
1097                                         dhcp_ip = dhcpmeshnet:minhost():string()
1098                                         dhcp_mask = dhcpmeshnet:mask():string()
1099                                         dhcp_network = dhcpmeshnet:network():string()
1100                                         uci:section("olsrd", "Hna4", nil, {
1101                                                 netmask  = dhcp_mask,
1102                                                 netaddr  = dhcp_network
1103                                         })
1104                                         uci:foreach("olsrd", "LoadPlugin",
1105                                                 function(s)             
1106                                                         if s.library == "olsrd_p2pd.so.0.1.0" then
1107                                                                 uci:set("olsrd", s['.name'], "ignore", "0")
1108                                                                 local nonolsr = uci:get("olsrd", s['.name'], "NonOlsrIf") or ""
1109                                                                 uci:set("olsrd", s['.name'], "NonOlsrIf", device .." ".. nonolsr)
1110                                                         end
1111                                                 end)
1112                                 else
1113                                         local subnet_prefix = tonumber(uci:get("freifunk", community, "splash_prefix")) or 27
1114                                         local pool_network = uci:get("freifunk", community, "splash_network") or "10.104.0.0/16"
1115                                         local pool = luci.ip.IPv4(pool_network)
1116                                         local ip = tostring(node_ip)
1117                                         if pool and ip then
1118                                                 local hosts_per_subnet = 2^(32 - subnet_prefix)
1119                                                 local number_of_subnets = (2^pool:prefix())/hosts_per_subnet
1120                                                 local seed1, seed2 = ip:match("(%d+)%.(%d+)$")
1121                                                 if seed1 and seed2 then
1122                                                         math.randomseed(seed1 * seed2)
1123                                                 end
1124                                                 local subnet = pool:add(hosts_per_subnet * math.random(number_of_subnets))
1125                                                 dhcp_ip = subnet:network(subnet_prefix):add(1):string()
1126                                                 dhcp_mask = subnet:mask(subnet_prefix):string()
1127                                         end
1128                                 end
1129                                 if dhcp_ip and dhcp_mask then
1130                                         -- Create alias
1131                                         local aliasbase = uci:get_all("freifunk", "alias")
1132                                         util.update(aliasbase, uci:get_all(external, "alias") or {})
1133                                         aliasbase.interface = device
1134                                         aliasbase.ipaddr = dhcp_ip
1135                                         aliasbase.netmask = dhcp_mask
1136                                         aliasbase.proto = "static"
1137                                         uci:section("network", "alias", device .. "dhcp", aliasbase)
1138                                         -- Create dhcp
1139                                         local dhcpbase = uci:get_all("freifunk", "dhcp")
1140                                         util.update(dhcpbase, uci:get_all(external, "dhcp") or {})
1141                                         dhcpbase.interface = device .. "dhcp"
1142                                         dhcpbase.force = 1
1143                                         uci:section("dhcp", "dhcp", device .. "dhcp", dhcpbase)
1144                                         uci:set_list("dhcp", device .. "dhcp", "dhcp_option", "119,olsr")
1145                                         -- Create firewall settings
1146                                         uci:delete_all("firewall", "rule", {
1147                                                 src="freifunk",
1148                                                 proto="udp",
1149                                                 dest_port="53"
1150                                         })
1151                                         uci:section("firewall", "rule", nil, {
1152                                                 src="freifunk",
1153                                                 proto="udp",
1154                                                 dest_port="53",
1155                                                 target="ACCEPT"
1156                                         })
1157                                         uci:delete_all("firewall", "rule", {
1158                                                 src="freifunk",
1159                                                 proto="udp",
1160                                                 src_port="68",
1161                                                 dest_port="67"
1162                                         })
1163                                         uci:section("firewall", "rule", nil, {
1164                                                 src="freifunk",
1165                                                 proto="udp",
1166                                                 src_port="68",
1167                                                 dest_port="67",
1168                                                 target="ACCEPT"
1169                                         })
1170                                         uci:delete_all("firewall", "rule", {
1171                                                 src="freifunk",
1172                                                 proto="tcp",
1173                                                 dest_port="8082",
1174                                         })
1175                                         uci:section("firewall", "rule", nil, {
1176                                                 src="freifunk",
1177                                                 proto="tcp",
1178                                                 dest_port="8082",
1179                                                 target="ACCEPT"
1180                                         })
1181                                         -- Register splash
1182                                         uci:section("luci_splash", "iface", nil, {network=device.."dhcp", zone="freifunk"})
1183                                         uci:save("luci_splash")
1184                                         -- Make sure that luci_splash is enabled
1185                                         sys.init.enable("luci_splash")
1186                                 end
1187                         end
1188                         uci:save("wireless")
1189                         uci:save("network")
1190                         uci:save("firewall")
1191                         uci:save("dhcp")
1192                 end
1193         end)
1194         --enable radvd
1195         if has_radvd then
1196                 sys.init.enable("radvd")
1197         end
1198         -- Enforce firewall include
1199         local has_include = false
1200         uci:foreach("firewall", "include",
1201                 function(section)
1202                         if section.path == "/etc/firewall.freifunk" then
1203                                 has_include = true
1204                         end
1205                 end)
1206
1207         if not has_include then
1208                 uci:section("firewall", "include", nil,
1209                         { path = "/etc/firewall.freifunk" })
1210         end
1211         -- Allow state: invalid packets
1212         uci:foreach("firewall", "defaults",
1213                 function(section)
1214                         uci:set("firewall", section[".name"], "drop_invalid", "0")
1215                 end)
1216
1217         -- Prepare advanced config
1218         local has_advanced = false
1219         uci:foreach("firewall", "advanced",
1220                 function(section) has_advanced = true end)
1221
1222         if not has_advanced then
1223                 uci:section("firewall", "advanced", nil,
1224                         { tcp_ecn = "0", ip_conntrack_max = "8192", tcp_westwood = "1" })
1225         end
1226         uci:save("wireless")
1227         uci:save("network")
1228         uci:save("firewall")
1229         uci:save("dhcp")
1230
1231         local new_hostname = uci:get("freifunk", "wizard", "hostname")
1232         local old_hostname = sys.hostname()
1233
1234         if has_hb then
1235                 local dhcphb = hb:formvalue(section)
1236                 if dhcphb then
1237                         uci:set("manager", "heartbeat", "enabled", "1")
1238                         -- Make sure that heartbeat is enabled
1239                         sys.init.enable("machash")
1240                 else
1241                         uci:set("manager", "heartbeat", "enabled", "0")
1242                         -- Make sure that heartbeat is enabled
1243                         sys.init.disable("machash")
1244                 end
1245                 uci:save("manager")
1246         end
1247
1248         local custom_hostname = hostname:formvalue(section)
1249         uci:foreach("system", "system",
1250                 function(s)
1251                         -- Make crond silent
1252                         uci:set("system", s['.name'], "cronloglevel", "10")
1253                         -- Make set timzone and zonename
1254                         uci:set("system", s['.name'], "zonename", "Europe/Berlin")
1255                         uci:set("system", s['.name'], "timezone", 'CET-1CEST,M3.5.0,M10.5.0/3')
1256                         -- Set hostname
1257                         if custom_hostname then
1258                                 uci:set("system", s['.name'], "hostname", custom_hostname)
1259                                 sys.hostname(custom_hostname)
1260                         else
1261                                 if new_hostname then
1262                                         if old_hostname == "OpenWrt" or old_hostname:match("^%d+-%d+-%d+-%d+$") then
1263                                                 uci:set("system", s['.name'], "hostname", new_hostname)
1264                                                 sys.hostname(new_hostname)
1265                                         end
1266                                 end
1267                         end
1268                 end)
1269
1270         -- Create time rdate_servers
1271         local rdate = uci:get_all("freifunk", "time")
1272         uci:delete_all("system", "time")
1273         uci:section("system", "time", "rdate_servers", rdate)
1274         rdate.server = rdate.rdate_servers
1275         rdate.rdate_servers = ""
1276         uci:delete_all("system", "rdate", nil)
1277         uci:section("system", "rdate", nil, rdate)
1278         uci:save("system")
1279
1280         -- Create http splash port 8082
1281         uci:set_list("uhttpd","main","listen_http",{"80"})
1282         uci:set_list("uhttpd","main","listen_https",{"443"})
1283         uci:save("uhttpd")
1284
1285         -- Read geos
1286         local latval = tonumber(lat:formvalue(section))
1287         local lonval = tonumber(lon:formvalue(section))
1288
1289         -- Save latlon to system too
1290         if latval and lonval then
1291                 uci:foreach("system", "system", function(s)
1292                         uci:set("system", s[".name"], "latlon",string.format("%.15f %.15f", latval, lonval))
1293                         uci:set("system", s[".name"], "latitude",string.format("%.15f", latval))
1294                         uci:set("system", s[".name"], "longitude",string.format("%.15f", lonval))
1295                 end)
1296         else
1297                 uci:foreach("system", "system", function(s)
1298                         uci:delete("system", s[".name"], "latlon")
1299                         uci:delete("system", s[".name"], "latitude")
1300                         uci:delete("system", s[".name"], "longitude")
1301                 end)
1302         end
1303         -- Delete old watchdog settings
1304         uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_watchdog.so.0.1"})
1305         -- Write new watchdog settings
1306         uci:section("olsrd", "LoadPlugin", nil, {
1307                 library  = "olsrd_watchdog.so.0.1",
1308                 file     = "/var/run/olsrd.watchdog",
1309                 interval = "30"
1310         })
1311
1312         -- Delete old nameservice settings
1313         uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_nameservice.so.0.3"})
1314         -- Write new nameservice settings
1315         uci:section("olsrd", "LoadPlugin", nil, {
1316                 library     = "olsrd_nameservice.so.0.3",
1317                 suffix      = "." .. suffix ,
1318                 hosts_file  = "/var/etc/hosts.olsr",
1319                 latlon_file = "/var/run/latlon.js",
1320                 lat         = latval and string.format("%.15f", latval) or "",
1321                 lon         = lonval and string.format("%.15f", lonval) or "",
1322                 services_file = "/var/etc/services.olsr"
1323         })
1324
1325         -- Import hosts and set domain
1326         uci:foreach("dhcp", "dnsmasq", function(s)
1327                 uci:set_list("dhcp", s[".name"], "addnhosts", "/var/etc/hosts.olsr")
1328                 uci:set("dhcp", s[".name"], "local", "/" .. suffix .. "/")
1329                 uci:set("dhcp", s[".name"], "domain", suffix)
1330         end)
1331
1332         -- Make sure that OLSR is enabled
1333         sys.init.enable("olsrd")
1334
1335         uci:save("olsrd")
1336         uci:save("dhcp")
1337         -- Import hosts and set domain
1338         if has_ipv6 then
1339                 uci:foreach("dhcp", "dnsmasq", function(s)
1340                         uci:set_list("dhcp", s[".name"], "addnhosts", {"/var/etc/hosts.olsr","/var/etc/hosts.olsr.ipv6"})
1341                 end)
1342         else
1343                 uci:foreach("dhcp", "dnsmasq", function(s)
1344                         uci:set_list("dhcp", s[".name"], "addnhosts", "/var/etc/hosts.olsr")
1345                 end)
1346         end
1347
1348         uci:save("dhcp")
1349
1350         -- Internet sharing
1351         local share_value = share:formvalue(section)
1352         if share_value == "1" then
1353                 uci:set("freifunk", "wizard", "netconfig", "1")
1354                 uci:section("firewall", "forwarding", nil, {src="freifunk", dest="wan"})
1355
1356                 if has_autoipv6 then
1357                         -- Set autoipv6 tunnel mode
1358                         uci:set("autoipv6", "olsr_node", "enable", "0")
1359                         uci:set("autoipv6", "tunnel", "enable", "1")
1360                         uci:save("autoipv6")
1361                 end
1362
1363                 -- Delete/Disable gateway plugin
1364                 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_dyn_gw.so.0.5"})
1365                 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_dyn_gw_plain.so.0.4"})
1366                 -- Enable gateway_plain plugin
1367                 uci:section("olsrd", "LoadPlugin", nil, {library="olsrd_dyn_gw_plain.so.0.4"})
1368                 sys.exec("chmod +x /etc/init.d/freifunk-p2pblock")
1369                 sys.init.enable("freifunk-p2pblock")
1370                 sys.init.enable("qos")
1371                 sys.exec('grep wan /etc/crontabs/root >/dev/null || echo "0 6 * * *     ifup wan" >> /etc/crontabs/root')
1372
1373                 if wansec:formvalue(section) == "1" then
1374                         uci:foreach("firewall", "zone",
1375                                 function(s)             
1376                                         if s.name == "wan" then
1377                                                 uci:set("firewall", s['.name'], "local_restrict", "1")
1378                                                 return false
1379                                         end
1380                                 end)
1381                 end
1382         else
1383                 uci:set("freifunk", "wizard", "netconfig", "0")
1384                 uci:save("freifunk")
1385                 if has_autoipv6 then
1386                         -- Set autoipv6 olsrd mode
1387                         uci:set("autoipv6", "olsr_node", "enable", "1")
1388                         uci:set("autoipv6", "tunnel", "enable", "0")
1389                         uci:save("autoipv6")
1390                 end
1391                 -- Delete gateway plugins
1392                 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_dyn_gw.so.0.5"})
1393                 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_dyn_gw_plain.so.0.4"})
1394                 -- Disable gateway_plain plugin
1395                 uci:section("olsrd", "LoadPlugin", nil, {
1396                         library     = "olsrd_dyn_gw_plain.so.0.4",
1397                         ignore      = 1,
1398                 })
1399                 sys.init.disable("freifunk-p2pblock")
1400                 sys.init.disable("qos")
1401                 sys.exec("chmod -x /etc/init.d/freifunk-p2pblock")
1402                 uci:delete_all("firewall", "forwarding", {src="freifunk", dest="wan"})
1403                 uci:foreach("firewall", "zone",
1404                         function(s)             
1405                                 if s.name == "wan" then
1406                                         uci:delete("firewall", s['.name'], "local_restrict")
1407                                         return false
1408                                 end
1409                         end)
1410         end
1411         -- Write gvpn dummy interface
1412         if has_l2gvpn then
1413                 if gvpn then
1414                         local vpn = gvpn:formvalue(section)
1415                         if vpn then
1416                                 uci:delete_all("l2gvpn", "l2gvpn")
1417                                 uci:delete_all("l2gvpn", "node")
1418                                 uci:delete_all("l2gvpn", "supernode")
1419                                 -- Write olsr tunnel interface options
1420                                 local olsr_gvpnifbase = uci:get_all("freifunk", "olsr_gvpninterface")
1421                                 util.update(olsr_gvpnifbase, uci:get_all(external, "olsr_gvpninterface") or {})
1422                                 uci:section("olsrd", "Interface", nil, olsr_gvpnifbase)
1423                                 local vpnip = gvpnip:formvalue(section)
1424                                 local gvpnif = uci:get_all("freifunk", "gvpn_node")
1425                                 util.update(gvpnif, uci:get_all(external, "gvpn_node") or {})
1426                                 if gvpnif and gvpnif.tundev and vpnip then
1427                                         uci:section("network", "interface", gvpnif.tundev, {
1428                                                 ifname  =gvpnif.tundev ,
1429                                                 proto   ="static" ,
1430                                                 ipaddr  =vpnip ,
1431                                                 netmask =gvpnif.subnet or "255.255.255.192" ,
1432                                         })
1433                                         gvpnif.ip=""
1434                                         gvpnif.subnet=""
1435                                         gvpnif.up=""
1436                                         gvpnif.down=""
1437                                         gvpnif.mac="00:00:48:"..string.format("%X",string.gsub( vpnip, ".*%." , "" ))..":00:00"
1438                                         tools.firewall_zone_add_interface("freifunk", gvpnif.tundev)
1439                                         uci:section("l2gvpn", "node" , gvpnif.community , gvpnif)
1440                                         uci:save("network")
1441                                         uci:save("l2gvpn")
1442                                         uci:save("firewall")
1443                                         uci:save("olsrd")
1444                                         sys.init.enable("l2gvpn")
1445                                 end
1446                         else
1447                                 -- Disable l2gvpn
1448                                 sys.exec("/etc/init.d/l2gvpn stop")
1449                                 sys.init.disable("l2gvpn")
1450                         end
1451                 end
1452         end
1453
1454         uci:save("freifunk")
1455         uci:save("firewall")
1456         uci:save("olsrd")
1457         uci:save("system")
1458 end
1459
1460 return f
1461