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