applications/ffwizard: Just realized we still need to set the bssid for ch. 10.
[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 == 10 then 
799                                         bssid = "02:CA:FF:EE:BA:BE" 
800                                 elseif chan >= 11 and chan <= 14 then
801                                         bssid = string.format("%X",channel) .. "2:CA:FF:EE:BA:BE"
802                                 elseif chan >= 36 and chan <= 64 then
803                                         hwmode = "11a"
804                                         mrate = ""
805                                         outdoor = 0
806                                         bssid = "00:" .. channel ..":CA:FF:EE:EE"
807                                 elseif chan >= 100 and chan <= 140 then
808                                         hwmode = "11a"
809                                         mrate = ""
810                                         outdoor = 1
811                                         bssid = "01:" .. string.sub(channel, 2) .. ":CA:FF:EE:EE"
812                                 end
813                                 devconfig.hwmode = hwmode
814                                 devconfig.outdoor = outdoor
815                         end
816                         ssid = ssid .. " - ch" .. channel
817                 end
818                 uci:tset("wireless", device, devconfig)
819                 -- Create wifi iface
820                 local ifconfig = uci:get_all("freifunk", "wifi_iface")
821                 util.update(ifconfig, uci:get_all(external, "wifi_iface") or {})
822                 ifconfig.device = device
823                 ifconfig.network = nif
824                 ifconfig.ssid = ssid
825                 ifconfig.bssid = bssid
826                 ifconfig.encryption="none"
827                 -- Read Preset 
828                 local netconfig = uci:get_all("freifunk", "interface")
829                 util.update(netconfig, uci:get_all(external, "interface") or {})
830                 netconfig.proto = "static"
831                 netconfig.ipaddr = node_ip:string()
832                 if has_ipv6 then
833                         netconfig.ip6addr = node_ip6:string()
834                 end
835                 uci:section("network", "interface", nif, netconfig)
836                 if has_radvd then
837                         uci:section("radvd", "interface", nil, {
838                                 interface          =nif,
839                                 AdvSendAdvert      =1,
840                                 AdvManagedFlag     =0,
841                                 AdvOtherConfigFlag =0,
842                                 ignore             =0
843                         })
844                         uci:section("radvd", "prefix", nil, {
845                                 interface          =nif,
846                                 AdvOnLink          =1,
847                                 AdvAutonomous      =1,
848                                 AdvRouterAddr      =0,
849                                 ignore             =0,
850                         })
851                         uci:save("radvd")
852                 end
853                 local new_hostname = node_ip:string():gsub("%.", "-")
854                 uci:set("freifunk", "wizard", "hostname", new_hostname)
855                 uci:save("freifunk")
856                 tools.firewall_zone_add_interface("freifunk", nif)
857                 uci:save("firewall")
858                 -- Write new olsrv4 interface
859                 local olsrifbase = uci:get_all("freifunk", "olsr_interface")
860                 util.update(olsrifbase, uci:get_all(external, "olsr_interface") or {})
861                 olsrifbase.interface = nif
862                 olsrifbase.ignore    = "0"
863                 uci:section("olsrd", "Interface", nil, olsrifbase)
864                 -- Collect MESH DHCP IP NET
865                 local client = luci.http.formvalue("cbid.ffwizward.1.client_" .. device)
866                 if client then
867                         local dhcpmeshnet = luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device))
868                         if has_hb then
869                                 local ifacelist = uci:get_list("manager", "heartbeat", "interface") or {}
870                                 table.insert(ifacelist,nif .. "dhcp")
871                                 uci:set_list("manager", "heartbeat", "interface", ifacelist)
872                                 uci:save("manager")
873                         end
874                         if dhcpmeshnet then
875                                 if not dhcpmeshnet:minhost() or not dhcpmeshnet:mask() then
876                                         dhcpmesh.tag_missing[section] = true
877                                         dhcpmeshnet = nil
878                                         return
879                                 end
880                                 dhcp_ip = dhcpmeshnet:minhost():string()
881                                 dhcp_mask = dhcpmeshnet:mask():string()
882                                 dhcp_network = dhcpmeshnet:network():string()
883                                 uci:section("olsrd", "Hna4", nil, {
884                                         netmask  = dhcp_mask,
885                                         netaddr  = dhcp_network
886                                 })
887                                 uci:foreach("olsrd", "LoadPlugin",
888                                         function(s)             
889                                                 if s.library == "olsrd_p2pd.so.0.1.0" then
890                                                         uci:set("olsrd", s['.name'], "ignore", "0")
891                                                         local nonolsr = uci:get("olsrd", s['.name'], "NonOlsrIf") or ""
892                                                         vap = luci.http.formvalue("cbid.ffwizward.1.vap_" .. device)
893                                                         if vap then
894                                                                 nonolsr = nif.."dhcp "..nonolsr
895                                                         else
896                                                                 nonolsr = nif.." "..nonolsr
897                                                         end
898                                                         uci:set("olsrd", s['.name'], "NonOlsrIf", nonolsr)
899                                                 end
900                                         end)
901                         else
902                                 local subnet_prefix = tonumber(uci:get("freifunk", community, "splash_prefix")) or 27
903                                 local pool_network = uci:get("freifunk", community, "splash_network") or "10.104.0.0/16"
904                                 local pool = luci.ip.IPv4(pool_network)
905                                 local ip = tostring(node_ip)
906                                 if pool and ip then
907                                         local hosts_per_subnet = 2^(32 - subnet_prefix)
908                                         local number_of_subnets = (2^pool:prefix())/hosts_per_subnet
909                                         local seed1, seed2 = ip:match("(%d+)%.(%d+)$")
910                                         if seed1 and seed2 then
911                                                 math.randomseed(seed1 * seed2)
912                                         end
913                                         local subnet = pool:add(hosts_per_subnet * math.random(number_of_subnets))
914                                         dhcp_ip = subnet:network(subnet_prefix):add(1):string()
915                                         dhcp_mask = subnet:mask(subnet_prefix):string()
916                                 end
917                         end
918                         if dhcp_ip and dhcp_mask then
919                                 -- Create alias
920                                 local aliasbase = uci:get_all("freifunk", "alias")
921                                 util.update(aliasbase, uci:get_all(external, "alias") or {})
922                                 aliasbase.ipaddr = dhcp_ip
923                                 aliasbase.netmask = dhcp_mask
924                                 aliasbase.proto = "static"
925                                 vap = luci.http.formvalue("cbid.ffwizward.1.vap_" .. device)
926                                 if vap then
927                                         uci:section("network", "interface", nif .. "dhcp", aliasbase)
928                                         uci:section("wireless", "wifi-iface", nil, {
929                                                 device     =device,
930                                                 mode       ="ap",
931                                                 encryption ="none",
932                                                 network    =nif .. "dhcp",
933                                                 ssid       ="AP-" .. ssid
934                                         })
935                                         if has_radvd then
936                                                 uci:section("radvd", "interface", nil, {
937                                                         interface          =nif .. "dhcp",
938                                                         AdvSendAdvert      =1,
939                                                         AdvManagedFlag     =0,
940                                                         AdvOtherConfigFlag =0,
941                                                         ignore             =0
942                                                 })
943                                                 uci:section("radvd", "prefix", nil, {
944                                                         interface          =nif .. "dhcp",
945                                                         AdvOnLink          =1,
946                                                         AdvAutonomous      =1,
947                                                         AdvRouterAddr      =0,
948                                                         ignore             =0
949                                                 })
950                                                 uci:save("radvd")
951                                         end
952                                         tools.firewall_zone_add_interface("freifunk", nif .. "dhcp")
953                                         uci:save("wireless")
954                                         ifconfig.mcast_rate = nil
955                                         ifconfig.encryption="none"
956                                 else
957                                         aliasbase.interface = nif
958                                         uci:section("network", "alias", nif .. "dhcp", aliasbase)
959                                 end
960                                 -- Create dhcp
961                                 local dhcpbase = uci:get_all("freifunk", "dhcp")
962                                 util.update(dhcpbase, uci:get_all(external, "dhcp") or {})
963                                 dhcpbase.interface = nif .. "dhcp"
964                                 dhcpbase.force = 1
965                                 uci:section("dhcp", "dhcp", nif .. "dhcp", dhcpbase)
966                                 uci:set_list("dhcp", nif .. "dhcp", "dhcp_option", "119,olsr")
967                                 -- Create firewall settings
968                                 uci:delete_all("firewall", "rule", {
969                                         src="freifunk",
970                                         proto="udp",
971                                         dest_port="53"
972                                 })
973                                 uci:section("firewall", "rule", nil, {
974                                         src="freifunk",
975                                         proto="udp",
976                                         dest_port="53",
977                                         target="ACCEPT"
978                                 })
979                                 uci:delete_all("firewall", "rule", {
980                                         src="freifunk",
981                                         proto="udp",
982                                         src_port="68",
983                                         dest_port="67"
984                                 })
985                                 uci:section("firewall", "rule", nil, {
986                                         src="freifunk",
987                                         proto="udp",
988                                         src_port="68",
989                                         dest_port="67",
990                                         target="ACCEPT"
991                                 })
992                                 uci:delete_all("firewall", "rule", {
993                                         src="freifunk",
994                                         proto="tcp",
995                                         dest_port="8082",
996                                 })
997                                 uci:section("firewall", "rule", nil, {
998                                         src="freifunk",
999                                         proto="tcp",
1000                                         dest_port="8082",
1001                                         target="ACCEPT"
1002                                 })
1003                                 -- Register splash
1004                                 uci:section("luci_splash", "iface", nil, {network=nif.."dhcp", zone="freifunk"})
1005                                 uci:save("luci_splash")
1006                                 -- Make sure that luci_splash is enabled
1007                                 sys.init.enable("luci_splash")
1008                         end
1009                 else
1010                         -- Delete old splash
1011                         uci:delete_all("luci_splash", "iface", {network=device.."dhcp", zone="freifunk"})
1012                 end
1013                 --Write Ad-Hoc wifi section after AP wifi section
1014                 uci:section("wireless", "wifi-iface", nil, ifconfig)
1015                 uci:save("network")
1016                 uci:save("wireless")
1017                 uci:save("network")
1018                 uci:save("firewall")
1019                 uci:save("dhcp")
1020         end)
1021         -- Create wired ip and firewall config
1022         uci:foreach("network", "interface",
1023                 function(sec)
1024                 local device = sec[".name"]
1025                 if not luci.http.formvalue("cbid.ffwizward.1.device_" .. device) then
1026                         return
1027                 end
1028                 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
1029                         local node_ip
1030                         node_ip = luci.http.formvalue("cbid.ffwizward.1.meship_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.meship_" .. device))
1031                         if has_ipv6 then
1032                                 node_ip6 = luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device) and ip.IPv6(luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device))
1033                         end
1034                         if not node_ip or not network or not network:contains(node_ip) then
1035                                 meship.tag_missing[section] = true
1036                                 node_ip = nil
1037                                 return
1038                         end
1039                         -- Cleanup
1040                         tools.firewall_zone_remove_interface(device, device)
1041                         uci:delete_all("firewall","zone", {name=device})
1042                         uci:delete_all("firewall","forwarding", {src=device})
1043                         uci:delete_all("firewall","forwarding", {dest=device})
1044                         uci:delete("network", device .. "dhcp")
1045                         -- Delete old dhcp
1046                         uci:delete("dhcp", device)
1047                         uci:delete("dhcp", device .. "dhcp")
1048                         -- Delete old splash
1049                         uci:delete_all("luci_splash", "iface", {network=device.."dhcp", zone="freifunk"})
1050                         if has_radvd then
1051                                 uci:delete_all("radvd", "interface", {interface=device.."dhcp"})
1052                                 uci:delete_all("radvd", "interface", {interface=device})
1053                                 uci:delete_all("radvd", "prefix", {interface=device.."dhcp"})
1054                                 uci:delete_all("radvd", "prefix", {interface=device})
1055                         end
1056                         -- New Config
1057                         local netconfig = uci:get_all("freifunk", "interface")
1058                         util.update(netconfig, uci:get_all(external, "interface") or {})
1059                         netconfig.proto = "static"
1060                         netconfig.ipaddr = node_ip:string()
1061                         if has_ipv6 then
1062                                 netconfig.ip6addr = node_ip6:string()
1063                         end
1064                         uci:section("network", "interface", device, netconfig)
1065                         uci:save("network")
1066                         if has_radvd then
1067                                 uci:section("radvd", "interface", nil, {
1068                                         interface          =device,
1069                                         AdvSendAdvert      =1,
1070                                         AdvManagedFlag     =0,
1071                                         AdvOtherConfigFlag =0,
1072                                         ignore             =0
1073                                 })
1074                                 uci:section("radvd", "prefix", nil, {
1075                                         interface          =device,
1076                                         AdvOnLink          =1,
1077                                         AdvAutonomous      =1,
1078                                         AdvRouterAddr      =0,
1079                                         ignore             =0,
1080                                 })
1081                                 uci:save("radvd")
1082                         end
1083                         local new_hostname = node_ip:string():gsub("%.", "-")
1084                         uci:set("freifunk", "wizard", "hostname", new_hostname)
1085                         uci:save("freifunk")
1086                         tools.firewall_zone_add_interface("freifunk", device)
1087                         uci:save("firewall")
1088                         -- Write new olsrv4 interface
1089                         local olsrifbase = uci:get_all("freifunk", "olsr_interface")
1090                         util.update(olsrifbase, uci:get_all(external, "olsr_interface") or {})
1091                         olsrifbase.interface = device
1092                         olsrifbase.ignore    = "0"
1093                         uci:section("olsrd", "Interface", nil, olsrifbase)
1094                         olsrifbase.Mode = 'ether'
1095                         -- Collect MESH DHCP IP NET
1096                         local client = luci.http.formvalue("cbid.ffwizward.1.client_" .. device)
1097                         if client then
1098                                 local dhcpmeshnet = luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device))
1099                                 if has_hb then
1100                                         local ifacelist = uci:get_list("manager", "heartbeat", "interface") or {}
1101                                         table.insert(ifacelist,device .. "dhcp")
1102                                         uci:set_list("manager", "heartbeat", "interface", ifacelist)
1103                                         uci:save("manager")
1104                                 end
1105                                 if dhcpmeshnet then
1106                                         if not dhcpmeshnet:minhost() or not dhcpmeshnet:mask() then
1107                                                 dhcpmesh.tag_missing[section] = true
1108                                                 dhcpmeshnet = nil
1109                                                 return
1110                                         end
1111                                         dhcp_ip = dhcpmeshnet:minhost():string()
1112                                         dhcp_mask = dhcpmeshnet:mask():string()
1113                                         dhcp_network = dhcpmeshnet:network():string()
1114                                         uci:section("olsrd", "Hna4", nil, {
1115                                                 netmask  = dhcp_mask,
1116                                                 netaddr  = dhcp_network
1117                                         })
1118                                         uci:foreach("olsrd", "LoadPlugin",
1119                                                 function(s)             
1120                                                         if s.library == "olsrd_p2pd.so.0.1.0" then
1121                                                                 uci:set("olsrd", s['.name'], "ignore", "0")
1122                                                                 local nonolsr = uci:get("olsrd", s['.name'], "NonOlsrIf") or ""
1123                                                                 uci:set("olsrd", s['.name'], "NonOlsrIf", device .." ".. nonolsr)
1124                                                         end
1125                                                 end)
1126                                 else
1127                                         local subnet_prefix = tonumber(uci:get("freifunk", community, "splash_prefix")) or 27
1128                                         local pool_network = uci:get("freifunk", community, "splash_network") or "10.104.0.0/16"
1129                                         local pool = luci.ip.IPv4(pool_network)
1130                                         local ip = tostring(node_ip)
1131                                         if pool and ip then
1132                                                 local hosts_per_subnet = 2^(32 - subnet_prefix)
1133                                                 local number_of_subnets = (2^pool:prefix())/hosts_per_subnet
1134                                                 local seed1, seed2 = ip:match("(%d+)%.(%d+)$")
1135                                                 if seed1 and seed2 then
1136                                                         math.randomseed(seed1 * seed2)
1137                                                 end
1138                                                 local subnet = pool:add(hosts_per_subnet * math.random(number_of_subnets))
1139                                                 dhcp_ip = subnet:network(subnet_prefix):add(1):string()
1140                                                 dhcp_mask = subnet:mask(subnet_prefix):string()
1141                                         end
1142                                 end
1143                                 if dhcp_ip and dhcp_mask then
1144                                         -- Create alias
1145                                         local aliasbase = uci:get_all("freifunk", "alias")
1146                                         util.update(aliasbase, uci:get_all(external, "alias") or {})
1147                                         aliasbase.interface = device
1148                                         aliasbase.ipaddr = dhcp_ip
1149                                         aliasbase.netmask = dhcp_mask
1150                                         aliasbase.proto = "static"
1151                                         uci:section("network", "alias", device .. "dhcp", aliasbase)
1152                                         -- Create dhcp
1153                                         local dhcpbase = uci:get_all("freifunk", "dhcp")
1154                                         util.update(dhcpbase, uci:get_all(external, "dhcp") or {})
1155                                         dhcpbase.interface = device .. "dhcp"
1156                                         dhcpbase.force = 1
1157                                         uci:section("dhcp", "dhcp", device .. "dhcp", dhcpbase)
1158                                         uci:set_list("dhcp", device .. "dhcp", "dhcp_option", "119,olsr")
1159                                         -- Create firewall settings
1160                                         uci:delete_all("firewall", "rule", {
1161                                                 src="freifunk",
1162                                                 proto="udp",
1163                                                 dest_port="53"
1164                                         })
1165                                         uci:section("firewall", "rule", nil, {
1166                                                 src="freifunk",
1167                                                 proto="udp",
1168                                                 dest_port="53",
1169                                                 target="ACCEPT"
1170                                         })
1171                                         uci:delete_all("firewall", "rule", {
1172                                                 src="freifunk",
1173                                                 proto="udp",
1174                                                 src_port="68",
1175                                                 dest_port="67"
1176                                         })
1177                                         uci:section("firewall", "rule", nil, {
1178                                                 src="freifunk",
1179                                                 proto="udp",
1180                                                 src_port="68",
1181                                                 dest_port="67",
1182                                                 target="ACCEPT"
1183                                         })
1184                                         uci:delete_all("firewall", "rule", {
1185                                                 src="freifunk",
1186                                                 proto="tcp",
1187                                                 dest_port="8082",
1188                                         })
1189                                         uci:section("firewall", "rule", nil, {
1190                                                 src="freifunk",
1191                                                 proto="tcp",
1192                                                 dest_port="8082",
1193                                                 target="ACCEPT"
1194                                         })
1195                                         -- Register splash
1196                                         uci:section("luci_splash", "iface", nil, {network=device.."dhcp", zone="freifunk"})
1197                                         uci:save("luci_splash")
1198                                         -- Make sure that luci_splash is enabled
1199                                         sys.init.enable("luci_splash")
1200                                 end
1201                         end
1202                         uci:save("wireless")
1203                         uci:save("network")
1204                         uci:save("firewall")
1205                         uci:save("dhcp")
1206                 end
1207         end)
1208         --enable radvd
1209         if has_radvd then
1210                 sys.init.enable("radvd")
1211         end
1212         -- Enforce firewall include
1213         local has_include = false
1214         uci:foreach("firewall", "include",
1215                 function(section)
1216                         if section.path == "/etc/firewall.freifunk" then
1217                                 has_include = true
1218                         end
1219                 end)
1220
1221         if not has_include then
1222                 uci:section("firewall", "include", nil,
1223                         { path = "/etc/firewall.freifunk" })
1224         end
1225         -- Allow state: invalid packets
1226         uci:foreach("firewall", "defaults",
1227                 function(section)
1228                         uci:set("firewall", section[".name"], "drop_invalid", "0")
1229                 end)
1230
1231         -- Prepare advanced config
1232         local has_advanced = false
1233         uci:foreach("firewall", "advanced",
1234                 function(section) has_advanced = true end)
1235
1236         if not has_advanced then
1237                 uci:section("firewall", "advanced", nil,
1238                         { tcp_ecn = "0", ip_conntrack_max = "8192", tcp_westwood = "1" })
1239         end
1240         uci:save("wireless")
1241         uci:save("network")
1242         uci:save("firewall")
1243         uci:save("dhcp")
1244
1245         local new_hostname = uci:get("freifunk", "wizard", "hostname")
1246         local old_hostname = sys.hostname()
1247
1248         if has_hb then
1249                 local dhcphb = hb:formvalue(section)
1250                 if dhcphb then
1251                         uci:set("manager", "heartbeat", "enabled", "1")
1252                         -- Make sure that heartbeat is enabled
1253                         sys.init.enable("machash")
1254                 else
1255                         uci:set("manager", "heartbeat", "enabled", "0")
1256                         -- Make sure that heartbeat is enabled
1257                         sys.init.disable("machash")
1258                 end
1259                 uci:save("manager")
1260         end
1261
1262         local custom_hostname = hostname:formvalue(section)
1263         uci:foreach("system", "system",
1264                 function(s)
1265                         -- Make crond silent
1266                         uci:set("system", s['.name'], "cronloglevel", "10")
1267                         -- Make set timzone and zonename
1268                         uci:set("system", s['.name'], "zonename", "Europe/Berlin")
1269                         uci:set("system", s['.name'], "timezone", 'CET-1CEST,M3.5.0,M10.5.0/3')
1270                         -- Set hostname
1271                         if custom_hostname then
1272                                 uci:set("system", s['.name'], "hostname", custom_hostname)
1273                                 sys.hostname(custom_hostname)
1274                         else
1275                                 if new_hostname then
1276                                         if old_hostname == "OpenWrt" or old_hostname:match("^%d+-%d+-%d+-%d+$") then
1277                                                 uci:set("system", s['.name'], "hostname", new_hostname)
1278                                                 sys.hostname(new_hostname)
1279                                         end
1280                                 end
1281                         end
1282                 end)
1283
1284         -- Create time rdate_servers
1285         local rdate = uci:get_all("freifunk", "time")
1286         uci:delete_all("system", "time")
1287         uci:section("system", "time", "rdate_servers", rdate)
1288         rdate.server = rdate.rdate_servers
1289         rdate.rdate_servers = ""
1290         uci:delete_all("system", "rdate", nil)
1291         uci:section("system", "rdate", nil, rdate)
1292         uci:save("system")
1293
1294         -- Create http splash port 8082
1295         uci:set_list("uhttpd","main","listen_http",{"80"})
1296         uci:set_list("uhttpd","main","listen_https",{"443"})
1297         uci:save("uhttpd")
1298
1299         -- Read geos
1300         local latval = tonumber(lat:formvalue(section))
1301         local lonval = tonumber(lon:formvalue(section))
1302
1303         -- Save latlon to system too
1304         if latval and lonval then
1305                 uci:foreach("system", "system", function(s)
1306                         uci:set("system", s[".name"], "latlon",string.format("%.15f %.15f", latval, lonval))
1307                         uci:set("system", s[".name"], "latitude",string.format("%.15f", latval))
1308                         uci:set("system", s[".name"], "longitude",string.format("%.15f", lonval))
1309                 end)
1310         else
1311                 uci:foreach("system", "system", function(s)
1312                         uci:delete("system", s[".name"], "latlon")
1313                         uci:delete("system", s[".name"], "latitude")
1314                         uci:delete("system", s[".name"], "longitude")
1315                 end)
1316         end
1317         -- Delete old watchdog settings
1318         uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_watchdog.so.0.1"})
1319         -- Write new watchdog settings
1320         uci:section("olsrd", "LoadPlugin", nil, {
1321                 library  = "olsrd_watchdog.so.0.1",
1322                 file     = "/var/run/olsrd.watchdog",
1323                 interval = "30"
1324         })
1325
1326         -- Delete old nameservice settings
1327         uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_nameservice.so.0.3"})
1328         -- Write new nameservice settings
1329         uci:section("olsrd", "LoadPlugin", nil, {
1330                 library     = "olsrd_nameservice.so.0.3",
1331                 suffix      = "." .. suffix ,
1332                 hosts_file  = "/var/etc/hosts.olsr",
1333                 latlon_file = "/var/run/latlon.js",
1334                 lat         = latval and string.format("%.15f", latval) or "",
1335                 lon         = lonval and string.format("%.15f", lonval) or "",
1336                 services_file = "/var/etc/services.olsr"
1337         })
1338
1339         -- Import hosts and set domain
1340         uci:foreach("dhcp", "dnsmasq", function(s)
1341                 uci:set_list("dhcp", s[".name"], "addnhosts", "/var/etc/hosts.olsr")
1342                 uci:set("dhcp", s[".name"], "local", "/" .. suffix .. "/")
1343                 uci:set("dhcp", s[".name"], "domain", suffix)
1344         end)
1345
1346         -- Make sure that OLSR is enabled
1347         sys.init.enable("olsrd")
1348
1349         uci:save("olsrd")
1350         uci:save("dhcp")
1351         -- Import hosts and set domain
1352         if has_ipv6 then
1353                 uci:foreach("dhcp", "dnsmasq", function(s)
1354                         uci:set_list("dhcp", s[".name"], "addnhosts", {"/var/etc/hosts.olsr","/var/etc/hosts.olsr.ipv6"})
1355                 end)
1356         else
1357                 uci:foreach("dhcp", "dnsmasq", function(s)
1358                         uci:set_list("dhcp", s[".name"], "addnhosts", "/var/etc/hosts.olsr")
1359                 end)
1360         end
1361
1362         uci:save("dhcp")
1363
1364         -- Internet sharing
1365         local share_value = share:formvalue(section)
1366         if share_value == "1" then
1367                 uci:set("freifunk", "wizard", "netconfig", "1")
1368                 uci:section("firewall", "forwarding", nil, {src="freifunk", dest="wan"})
1369
1370                 if has_autoipv6 then
1371                         -- Set autoipv6 tunnel mode
1372                         uci:set("autoipv6", "olsr_node", "enable", "0")
1373                         uci:set("autoipv6", "tunnel", "enable", "1")
1374                         uci:save("autoipv6")
1375                 end
1376
1377                 -- Delete/Disable gateway plugin
1378                 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_dyn_gw.so.0.5"})
1379                 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_dyn_gw_plain.so.0.4"})
1380                 -- Enable gateway_plain plugin
1381                 uci:section("olsrd", "LoadPlugin", nil, {library="olsrd_dyn_gw_plain.so.0.4"})
1382                 sys.exec("chmod +x /etc/init.d/freifunk-p2pblock")
1383                 sys.init.enable("freifunk-p2pblock")
1384                 sys.init.enable("qos")
1385                 sys.exec('grep wan /etc/crontabs/root >/dev/null || echo "0 6 * * *     ifup wan" >> /etc/crontabs/root')
1386
1387                 if wansec:formvalue(section) == "1" then
1388                         uci:foreach("firewall", "zone",
1389                                 function(s)             
1390                                         if s.name == "wan" then
1391                                                 uci:set("firewall", s['.name'], "local_restrict", "1")
1392                                                 return false
1393                                         end
1394                                 end)
1395                 end
1396         else
1397                 uci:set("freifunk", "wizard", "netconfig", "0")
1398                 uci:save("freifunk")
1399                 if has_autoipv6 then
1400                         -- Set autoipv6 olsrd mode
1401                         uci:set("autoipv6", "olsr_node", "enable", "1")
1402                         uci:set("autoipv6", "tunnel", "enable", "0")
1403                         uci:save("autoipv6")
1404                 end
1405                 -- Delete gateway plugins
1406                 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_dyn_gw.so.0.5"})
1407                 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_dyn_gw_plain.so.0.4"})
1408                 -- Disable gateway_plain plugin
1409                 uci:section("olsrd", "LoadPlugin", nil, {
1410                         library     = "olsrd_dyn_gw_plain.so.0.4",
1411                         ignore      = 1,
1412                 })
1413                 sys.init.disable("freifunk-p2pblock")
1414                 sys.init.disable("qos")
1415                 sys.exec("chmod -x /etc/init.d/freifunk-p2pblock")
1416                 uci:delete_all("firewall", "forwarding", {src="freifunk", dest="wan"})
1417                 uci:foreach("firewall", "zone",
1418                         function(s)             
1419                                 if s.name == "wan" then
1420                                         uci:delete("firewall", s['.name'], "local_restrict")
1421                                         return false
1422                                 end
1423                         end)
1424         end
1425         -- Write gvpn dummy interface
1426         if has_l2gvpn then
1427                 if gvpn then
1428                         local vpn = gvpn:formvalue(section)
1429                         if vpn then
1430                                 uci:delete_all("l2gvpn", "l2gvpn")
1431                                 uci:delete_all("l2gvpn", "node")
1432                                 uci:delete_all("l2gvpn", "supernode")
1433                                 -- Write olsr tunnel interface options
1434                                 local olsr_gvpnifbase = uci:get_all("freifunk", "olsr_gvpninterface")
1435                                 util.update(olsr_gvpnifbase, uci:get_all(external, "olsr_gvpninterface") or {})
1436                                 uci:section("olsrd", "Interface", nil, olsr_gvpnifbase)
1437                                 local vpnip = gvpnip:formvalue(section)
1438                                 local gvpnif = uci:get_all("freifunk", "gvpn_node")
1439                                 util.update(gvpnif, uci:get_all(external, "gvpn_node") or {})
1440                                 if gvpnif and gvpnif.tundev and vpnip then
1441                                         uci:section("network", "interface", gvpnif.tundev, {
1442                                                 ifname  =gvpnif.tundev ,
1443                                                 proto   ="static" ,
1444                                                 ipaddr  =vpnip ,
1445                                                 netmask =gvpnif.subnet or "255.255.255.192" ,
1446                                         })
1447                                         gvpnif.ip=""
1448                                         gvpnif.subnet=""
1449                                         gvpnif.up=""
1450                                         gvpnif.down=""
1451                                         gvpnif.mac="00:00:48:"..string.format("%X",string.gsub( vpnip, ".*%." , "" ))..":00:00"
1452                                         tools.firewall_zone_add_interface("freifunk", gvpnif.tundev)
1453                                         uci:section("l2gvpn", "node" , gvpnif.community , gvpnif)
1454                                         uci:save("network")
1455                                         uci:save("l2gvpn")
1456                                         uci:save("firewall")
1457                                         uci:save("olsrd")
1458                                         sys.init.enable("l2gvpn")
1459                                 end
1460                         else
1461                                 -- Disable l2gvpn
1462                                 sys.exec("/etc/init.d/l2gvpn stop")
1463                                 sys.init.disable("l2gvpn")
1464                         end
1465                 end
1466         end
1467
1468         uci:save("freifunk")
1469         uci:save("firewall")
1470         uci:save("olsrd")
1471         uci:save("system")
1472 end
1473
1474 return f
1475