f963c16fdff853a39cf36f45e48ca367507e8f5e
[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
36 luci.i18n.loadc("freifunk")
37
38 function get_mac(ix)
39         if string.find(ix, "radio") then
40                 ix = string.gsub(ix,"radio", 'wlan')
41         end
42         local mac = fs.readfile("/sys/class/net/" .. ix .. "/address")
43         if not mac then
44                 mac = luci.util.exec("ifconfig " .. ix)
45                 mac = mac and mac:match(" ([A-F0-9:]+)%s*\n")
46         else
47                 mac = mac:sub(1,17)
48         end
49         if mac and #mac > 0 then
50                 return mac:lower()
51         end
52         return "?"
53 end
54 function get_ula(imac)
55         if string.len(imac) == 17 then
56                 local mac1 = string.sub(imac,4,8)
57                 local mac2 = string.sub(imac,10,14)
58                 local mac3 = string.sub(imac,16,17)
59                 return 'fdca:ffee:babe::02'..mac1..'ff:fe'..mac2..mac3..'/64'
60         end
61         return "?"
62 end
63
64
65 -------------------- View --------------------
66 f = SimpleForm("ffwizward", "Freifunkassistent",
67  "Dieser Assistent unterstützt Sie bei der Einrichtung des Routers für das Freifunknetz.")
68 -- main netconfig
69 local newpsswd = has_rom and sys.exec("diff /rom/etc/passwd /etc/passwd")
70 if newpsswd ~= "" then
71         pw = f:field(Flag, "pw", "Router Passwort", "Setzen Sie den Haken, um Ihr Passwort zu ändern.")
72         function pw.cfgvalue(self, section)
73                 return 1
74         end
75 end
76
77 pw1 = f:field(Value, "pw1", translate("password"))
78 pw1.password = true
79 pw1.rmempty = false
80
81 pw2 = f:field(Value, "pw2", translate("confirmation"))
82 pw2.password = true
83 pw2.rmempty = false
84
85 function pw2.validate(self, value, section)
86         return pw1:formvalue(section) == value and value
87 end
88
89 if newpsswd ~= "" then
90         pw1:depends("pw", "1")
91         pw2:depends("pw", "1")
92 end
93
94 net = f:field(ListValue, "net", "Freifunk Community", "Nutzen Sie die Einstellungen der Freifunk Gemeinschaft in ihrer Nachbarschaft.")
95 net.rmempty = false
96 net.optional = false
97 uci:foreach("freifunk", "community", function(s)
98         net:value(s[".name"], "%s (%s)" % {s.name, s.mesh_network or "?"})
99 end)
100 function net.cfgvalue(self, section)
101         return uci:get("freifunk", "wizard", "net")
102 end
103 function net.write(self, section, value)
104         uci:set("freifunk", "wizard", "net", value)
105         uci:save("freifunk")
106 end
107 net_lat = f:field(ListValue, "net_lat", "", "")
108 net_lat:depends("net", "0")
109 net_lon = f:field(ListValue, "net_lon", "", "")
110 net_lon:depends("net", "0")
111
112 uci:foreach("freifunk", "community", function(s)
113         if s.latitude then
114                 net_lat:value(s[".name"], "%s" % {s.latitude or "?"})
115         end
116         if s.longitude then
117                 net_lon:value(s[".name"], "%s" % {s.longitude or "?"})
118         end
119 end)
120
121 -- hostname
122 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.")
123 hostname.rmempty = true
124 hostname.optional = false
125 function hostname.cfgvalue(self, section)
126         return sys.hostname()
127 end
128 function hostname.write(self, section, value)
129         uci:set("freifunk", "wizard", "hostname", value)
130         uci:save("freifunk")
131 end
132 function hostname.validate(self, value)
133         if (#value > 16) then
134                 return
135         elseif (string.find(value, "[^%w%_%-]")) then
136                 return
137         else
138                 return value
139         end
140 end
141
142 -- location
143 location = f:field(Value, "location", "Standort", "Geben Sie den Standort ihres Gerätes an")
144 location.rmempty = false
145 location.optional = false
146 function location.cfgvalue(self, section)
147         return uci:get("freifunk", "contact", "location")
148 end
149 function location.write(self, section, value)
150         uci:set("freifunk", "contact", "location", value)
151         uci:save("freifunk")
152 end
153
154 -- mail
155 mail = f:field(Value, "mail", "E-Mail", "Bitte hinterlegen Sie eine Kontaktadresse.")
156 mail.rmempty = false
157 mail.optional = false
158 function mail.cfgvalue(self, section)
159         return uci:get("freifunk", "contact", "mail")
160 end
161 function mail.write(self, section, value)
162         uci:set("freifunk", "contact", "mail", value)
163         uci:save("freifunk")
164 end
165 -- main netconfig
166 main = f:field(Flag, "netconfig", "Netzwerk einrichten", "Setzen Sie den Haken, wenn Sie Ihr Freifunk Netzwerk einrichten wollen.")
167 uci:foreach("wireless", "wifi-device",
168         function(section)
169                 local device = section[".name"]
170                 local dev = f:field(Flag, "device_" .. device , "<b>Drahtloses Netzwerk \"" .. device:upper() .. "\"</b> ", "Konfigurieren Sie Ihre drahtlose " .. device:upper() .. "Schnittstelle (WLAN).")
171                         dev:depends("netconfig", "1")
172                         dev.rmempty = false
173                         function dev.cfgvalue(self, section)
174                                 return uci:get("freifunk", "wizard", "device_" .. device)
175                         end
176                         function dev.write(self, sec, value)
177                                 if value then
178                                         uci:set("freifunk", "wizard", "device_" .. device, value)
179                                         uci:save("freifunk")
180                                 end
181                         end
182                 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.")
183                         chan:depends("device_" .. device, "1")
184                         chan.rmempty = true
185                         function chan.cfgvalue(self, section)
186                                 return uci:get("freifunk", "wizard", "chan_" .. device)
187                         end
188                         chan:value('default')
189                         for i = 1, 14, 1 do
190                                 chan:value(i)
191                         end
192                         for i = 36, 64, 4 do
193                                 chan:value(i)
194                         end
195                         for i = 100, 140, 4 do
196                                 chan:value(i)
197                         end
198                         function chan.write(self, sec, value)
199                                 if value then
200                                         uci:set("freifunk", "wizard", "chan_" .. device, value)
201                                         uci:save("freifunk")
202                                 end
203                         end
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 hb = f:field(Flag, "hb", "Heartbeat aktivieren","Dem Gerät erlauben anonyme Statistiken zu übertragen. (empfohlen)")
561 hb.rmempty = false
562 hb:depends("netconfig", "1")
563 function hb.cfgvalue(self, section)
564         return uci:get("freifunk", "wizard", "hb")
565 end
566 function hb.write(self, section, value)
567         uci:set("freifunk", "wizard", "hb", value)
568         uci:save("freifunk")
569 end
570
571 -------------------- Control --------------------
572 function f.handle(self, state, data)
573         if state == FORM_VALID then
574                 local debug = uci:get("freifunk", "wizard", "debug")
575                 if debug == "1" then
576                         if data.pw1 then
577                                 local stat = luci.sys.user.setpasswd("root", data.pw1) == 0
578                                 if stat then
579                                         f.message = translate("a_s_changepw_changed")
580                                 else
581                                         f.errmessage = translate("unknownerror")
582                                 end
583                         end
584                         data.pw1 = nil
585                         data.pw2 = nil
586                         luci.http.redirect(luci.dispatcher.build_url(unpack(luci.dispatcher.context.requested.path), "system", "system"))
587                 else
588                         if data.pw1 then
589                                 local stat = luci.sys.user.setpasswd("root", data.pw1) == 0
590 --                              if stat then
591 --                                      f.message = translate("a_s_changepw_changed")
592 --                      else
593 --                              f.errmessage = translate("unknownerror")
594                                 end
595                         data.pw1 = nil
596                         data.pw2 = nil
597                         uci:commit("freifunk")
598                         uci:commit("wireless")
599                         uci:commit("network")
600                         uci:commit("dhcp")
601                         uci:commit("luci_splash")
602                         uci:commit("firewall")
603                         uci:commit("system")
604                         uci:commit("uhttpd")
605                         uci:commit("olsrd")
606                         uci:commit("manager")
607                         if has_autoipv6 then
608                                 uci:commit("autoipv6")
609                         end
610                         if has_qos then
611                                 uci:commit("qos")
612                         end
613                         if has_l2gvpn then
614                                 uci:commit("l2gvpn")
615                         end
616                         if has_radvd then
617                                 uci:commit("radvd")
618                         end
619 -- the following line didn't work without admin-mini, for now i just replaced it with sys.exec... soma
620 --                      luci.http.redirect(luci.dispatcher.build_url(unpack(luci.dispatcher.context.requested.path), "system", "reboot") .. "?reboot=1")
621                         sys.exec("reboot")
622                 end
623                 return false
624         elseif state == FORM_INVALID then
625                 self.errmessage = "Ungültige Eingabe: Bitte die Formularfelder auf Fehler prüfen."
626         end
627         return true
628 end
629
630 local function _strip_internals(tbl)
631         tbl = tbl or {}
632         for k, v in pairs(tbl) do
633                 if k:sub(1, 1) == "." then
634                         tbl[k] = nil
635                 end
636         end
637         return tbl
638 end
639 -- Configure Freifunk checked
640 function main.write(self, section, value)
641         if value == "0" then
642                 uci:set("freifunk", "wizard", "netconfig", "0")
643                 uci:save("freifunk")
644                 return
645         end
646         -- Collect IP-Address
647         local community = net:formvalue(section)
648         suffix = uci:get("freifunk", community, "suffix") or "olsr"
649
650         -- Invalidate fields
651         if not community then
652                 net.tag_missing[section] = true
653                 return
654         end
655
656         uci:set("freifunk", "wizard", "netconfig", "1")
657         uci:save("freifunk")
658
659         local external
660         external = uci:get("freifunk", community, "external") or ""
661
662         local netname = "wireless"
663         local network
664         network = ip.IPv4(uci:get("freifunk", community, "mesh_network") or "104.0.0.0/8")
665
666         -- Tune community settings
667         if community and uci:get("freifunk", community) then
668                 uci:tset("freifunk", "community", uci:get_all("freifunk", community))
669         end
670
671         -- Cleanup
672         uci:delete_all("firewall","zone", {name="freifunk"})
673         uci:delete_all("firewall","forwarding", {dest="freifunk"})
674         uci:delete_all("firewall","forwarding", {src="freifunk"})
675         uci:delete_all("firewall","rule", {dest="freifunk"})
676         uci:delete_all("firewall","rule", {src="freifunk"})
677         uci:save("firewall")
678         -- Create firewall zone and add default rules (first time)
679         --                    firewall_create_zone("name"    , "input" , "output", "forward ", Masqurade)
680         local newzone = tools.firewall_create_zone("freifunk", "ACCEPT", "ACCEPT", "REJECT"  , true)
681         if newzone then
682                 uci:foreach("freifunk", "fw_forwarding", function(section)
683                         uci:section("firewall", "forwarding", nil, section)
684                 end)
685                 uci:foreach(external, "fw_forwarding", function(section)
686                         uci:section("firewall", "forwarding", nil, section)
687                 end)
688
689                 uci:foreach("freifunk", "fw_rule", function(section)
690                         uci:section("firewall", "rule", nil, section)
691                 end)
692                 uci:foreach(external, "fw_rule", function(section)
693                         uci:section("firewall", "rule", nil, section)
694                 end)
695         end
696         uci:save("firewall")
697         uci:delete("manager", "heartbeat", "interface")
698         uci:save("manager")
699         -- Delete olsrdv4
700         uci:delete_all("olsrd", "olsrd")
701         local olsrbase
702         olsrbase = uci:get_all("freifunk", "olsrd") or {}
703         util.update(olsrbase, uci:get_all(external, "olsrd") or {})
704         if has_ipv6 then
705                 olsrbase.IpVersion='6and4'
706         else
707                 olsrbase.IpVersion='4'
708         end
709         uci:section("olsrd", "olsrd", nil, olsrbase)
710         -- Delete olsrdv4 old p2pd settings
711         uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_mdns.so.1.0.0"})
712         uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_p2pd.so.0.1.0"})
713         -- Write olsrdv4 new p2pd settings
714         uci:section("olsrd", "LoadPlugin", nil, {
715                 library     = "olsrd_p2pd.so.0.1.0",
716                 P2pdTtl     = 10,
717                 UdpDestPort = "224.0.0.251 5353",
718                 ignore      = 1,
719         })
720         -- Delete http plugin
721         uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_httpinfo.so.0.1"})
722
723         -- Delete olsrdv4 old interface
724         uci:delete_all("olsrd", "Interface")
725         uci:delete_all("olsrd", "Hna4")
726         -- Create wireless ip4/ip6 and firewall config
727         uci:foreach("wireless", "wifi-device",
728         function(sec)
729                 local device = sec[".name"]
730                 if not luci.http.formvalue("cbid.ffwizward.1.device_" .. device) then
731                         return
732                 end
733                 node_ip = luci.http.formvalue("cbid.ffwizward.1.meship_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.meship_" .. device))
734                 if has_ipv6 then
735                         node_ip6 = luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device) and ip.IPv6(luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device))
736                 end
737                 if not node_ip or not network or not network:contains(node_ip) then
738                         meship.tag_missing[section] = true
739                         node_ip = nil
740                         return
741                 end
742                 -- rename the wireless interface s/wifi/wireless/
743                 local nif
744                 if string.find(device, "wifi") then
745                         nif = string.gsub(device,"wifi", netname)
746                 elseif string.find(device, "wl") then
747                         nif = string.gsub(device,"wl", netname)
748                 elseif string.find(device, "wlan") then
749                         nif = string.gsub(device,"wlan", netname)
750                 elseif string.find(device, "radio") then
751                         nif = string.gsub(device,"radio", netname)
752                 end
753                 -- Cleanup
754                 tools.wifi_delete_ifaces(device)
755                 -- tools.network_remove_interface(device)
756                 uci:delete("network", device .. "dhcp")
757                 uci:delete("network", device)
758                 tools.firewall_zone_remove_interface("freifunk", device)
759                 -- tools.network_remove_interface(nif)
760                 uci:delete("network", nif .. "dhcp")
761                 uci:delete("network", nif)
762                 tools.firewall_zone_remove_interface("freifunk", nif)
763                 -- Delete old dhcp
764                 uci:delete("dhcp", device)
765                 uci:delete("dhcp", device .. "dhcp")
766                 uci:delete("dhcp", nif)
767                 uci:delete("dhcp", nif .. "dhcp")
768                 -- Delete old splash
769                 uci:delete_all("luci_splash", "iface", {network=device.."dhcp", zone="freifunk"})
770                 uci:delete_all("luci_splash", "iface", {network=nif.."dhcp", zone="freifunk"})
771                 -- Delete old radvd
772                 if has_radvd then
773                         uci:delete_all("radvd", "interface", {interface=nif.."dhcp"})
774                         uci:delete_all("radvd", "interface", {interface=nif})
775                         uci:delete_all("radvd", "prefix", {interface=nif.."dhcp"})
776                         uci:delete_all("radvd", "prefix", {interface=nif})
777                 end
778                 -- New Config
779                 -- Tune wifi device
780                 local ssiduci = uci:get("freifunk", community, "ssid")
781                 local ssiddot = string.find(ssiduci,'%..*')
782                 local ssidshort
783                 if ssiddot then
784                         ssidshort = string.sub(ssiduci,ssiddot)
785                 else
786                         ssidshort = ssiduci
787                 end
788                 local devconfig = uci:get_all("freifunk", "wifi_device")
789                 util.update(devconfig, uci:get_all(external, "wifi_device") or {})
790                 local ssid = uci:get("freifunk", community, "ssid")
791                 local channel = luci.http.formvalue("cbid.ffwizward.1.chan_" .. device)
792                 local hwmode = "11bg"
793                 local bssid = "02:CA:FF:EE:BA:BE"
794                 local mrate = 5500
795                 if channel and channel ~= "default" then
796                         if devconfig.channel ~= channel then
797                                 devconfig.channel = channel
798                                 local chan = tonumber(channel)
799                                 if chan >= 0 and chan < 10 then
800                                         bssid = channel .. "2:CA:FF:EE:BA:BE"
801                                         ssid = "ch" .. channel .. ssidshort
802                                 elseif chan == 10 then
803                                         bssid = "02:CA:FF:EE:BA:BE"
804                                         ssid = "ch" .. channel .. ssidshort
805                                 elseif chan >= 11 and chan <= 14 then
806                                         bssid = string.format("%X",channel) .. "2:CA:FF:EE:BA:BE"
807                                         ssid = "ch" .. channel .. ssidshort
808                                 elseif chan >= 36 and chan <= 64 then
809                                         hwmode = "11a"
810                                         mrate = ""
811                                         outdoor = 0
812                                         bssid = "00:" .. channel ..":CA:FF:EE:EE"
813                                         ssid = "ch" .. channel .. ssidshort
814                                 elseif chan >= 100 and chan <= 140 then
815                                         hwmode = "11a"
816                                         mrate = ""
817                                         outdoor = 1
818                                         bssid = "01:" .. string.sub(channel, 2) .. ":CA:FF:EE:EE"
819                                         ssid = "ch" .. channel .. ssidshort
820                                 end
821                                 devconfig.hwmode = hwmode
822                                 devconfig.outdoor = outdoor
823                         end
824                 end
825                 uci:tset("wireless", device, devconfig)
826                 -- Create wifi iface
827                 local ifconfig = uci:get_all("freifunk", "wifi_iface")
828                 util.update(ifconfig, uci:get_all(external, "wifi_iface") or {})
829                 ifconfig.device = device
830                 ifconfig.network = nif
831                 if ssid then
832                         -- See Table https://kifuse02.pberg.freifunk.net/moin/channel-bssid-essid 
833                         ifconfig.ssid = ssid
834                 else
835                         ifconfig.ssid = "olsr.freifunk.net"
836                 end
837                 -- See Table https://kifuse02.pberg.freifunk.net/moin/channel-bssid-essid       
838                 ifconfig.bssid = bssid
839                 ifconfig.encryption="none"
840                 -- Read Preset 
841                 local netconfig = uci:get_all("freifunk", "interface")
842                 util.update(netconfig, uci:get_all(external, "interface") or {})
843                 netconfig.proto = "static"
844                 netconfig.ipaddr = node_ip:string()
845                 if has_ipv6 then
846                         netconfig.ip6addr = node_ip6:string()
847                 end
848                 uci:section("network", "interface", nif, netconfig)
849                 if has_radvd then
850                         uci:section("radvd", "interface", nil, {
851                                 interface          =nif,
852                                 AdvSendAdvert      =1,
853                                 AdvManagedFlag     =0,
854                                 AdvOtherConfigFlag =0,
855                                 ignore             =0
856                         })
857                         uci:section("radvd", "prefix", nil, {
858                                 interface          =nif,
859                                 AdvOnLink          =1,
860                                 AdvAutonomous      =1,
861                                 AdvRouterAddr      =0,
862                                 ignore             =0,
863                         })
864                         uci:save("radvd")
865                 end
866                 local new_hostname = node_ip:string():gsub("%.", "-")
867                 uci:set("freifunk", "wizard", "hostname", new_hostname)
868                 uci:save("freifunk")
869                 tools.firewall_zone_add_interface("freifunk", nif)
870                 uci:save("firewall")
871                 -- Write new olsrv4 interface
872                 local olsrifbase = uci:get_all("freifunk", "olsr_interface")
873                 util.update(olsrifbase, uci:get_all(external, "olsr_interface") or {})
874                 olsrifbase.interface = nif
875                 olsrifbase.ignore    = "0"
876                 uci:section("olsrd", "Interface", nil, olsrifbase)
877                 -- Collect MESH DHCP IP NET
878                 local client = luci.http.formvalue("cbid.ffwizward.1.client_" .. device)
879                 if client then
880                         local dhcpmeshnet = luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device))
881                         local ifacelist = uci:get_list("manager", "heartbeat", "interface") or {}
882                         table.insert(ifacelist,nif .. "dhcp")
883                         uci:set_list("manager", "heartbeat", "interface", ifacelist)
884                         uci:save("manager")
885                         if dhcpmeshnet then
886                                 if not dhcpmeshnet:minhost() or not dhcpmeshnet:mask() then
887                                         dhcpmesh.tag_missing[section] = true
888                                         dhcpmeshnet = nil
889                                         return
890                                 end
891                                 dhcp_ip = dhcpmeshnet:minhost():string()
892                                 dhcp_mask = dhcpmeshnet:mask():string()
893                                 dhcp_network = dhcpmeshnet:network():string()
894                                 uci:section("olsrd", "Hna4", nil, {
895                                         netmask  = dhcp_mask,
896                                         netaddr  = dhcp_network
897                                 })
898                                 uci:foreach("olsrd", "LoadPlugin",
899                                         function(s)             
900                                                 if s.library == "olsrd_p2pd.so.0.1.0" then
901                                                         uci:set("olsrd", s['.name'], "ignore", "0")
902                                                         local nonolsr = uci:get("olsrd", s['.name'], "NonOlsrIf") or ""
903                                                         vap = luci.http.formvalue("cbid.ffwizward.1.vap_" .. device)
904                                                         if vap then
905                                                                 nonolsr = nif.."dhcp "..nonolsr
906                                                         else
907                                                                 nonolsr = nif.." "..nonolsr
908                                                         end
909                                                         uci:set("olsrd", s['.name'], "NonOlsrIf", nonolsr)
910                                                 end
911                                         end)
912                         else
913                                 local subnet_prefix = tonumber(uci:get("freifunk", community, "splash_prefix")) or 27
914                                 local pool_network = uci:get("freifunk", community, "splash_network") or "10.104.0.0/16"
915                                 local pool = luci.ip.IPv4(pool_network)
916                                 local ip = tostring(node_ip)
917                                 if pool and ip then
918                                         local hosts_per_subnet = 2^(32 - subnet_prefix)
919                                         local number_of_subnets = (2^pool:prefix())/hosts_per_subnet
920                                         local seed1, seed2 = ip:match("(%d+)%.(%d+)$")
921                                         if seed1 and seed2 then
922                                                 math.randomseed(seed1 * seed2)
923                                         end
924                                         local subnet = pool:add(hosts_per_subnet * math.random(number_of_subnets))
925                                         dhcp_ip = subnet:network(subnet_prefix):add(1):string()
926                                         dhcp_mask = subnet:mask(subnet_prefix):string()
927                                 end
928                         end
929                         if dhcp_ip and dhcp_mask then
930                                 -- Create alias
931                                 local aliasbase = uci:get_all("freifunk", "alias")
932                                 util.update(aliasbase, uci:get_all(external, "alias") or {})
933                                 aliasbase.ipaddr = dhcp_ip
934                                 aliasbase.netmask = dhcp_mask
935                                 aliasbase.proto = "static"
936                                 vap = luci.http.formvalue("cbid.ffwizward.1.vap_" .. device)
937                                 if vap then
938                                         uci:section("network", "interface", nif .. "dhcp", aliasbase)
939                                         uci:section("wireless", "wifi-iface", nil, {
940                                                 device     =device,
941                                                 mode       ="ap",
942                                                 encryption ="none",
943                                                 network    =nif.."dhcp",
944                                                 ssid       ="AP"..ssidshort
945                                         })
946                                         if has_radvd then
947                                                 uci:section("radvd", "interface", nil, {
948                                                         interface          =nif .. "dhcp",
949                                                         AdvSendAdvert      =1,
950                                                         AdvManagedFlag     =0,
951                                                         AdvOtherConfigFlag =0,
952                                                         ignore             =0
953                                                 })
954                                                 uci:section("radvd", "prefix", nil, {
955                                                         interface          =nif .. "dhcp",
956                                                         AdvOnLink          =1,
957                                                         AdvAutonomous      =1,
958                                                         AdvRouterAddr      =0,
959                                                         ignore             =0
960                                                 })
961                                                 uci:save("radvd")
962                                         end
963                                         tools.firewall_zone_add_interface("freifunk", nif .. "dhcp")
964                                         uci:save("wireless")
965                                         ifconfig.mcast_rate = nil
966                                         ifconfig.encryption="none"
967                                 else
968                                         aliasbase.interface = nif
969                                         uci:section("network", "alias", nif .. "dhcp", aliasbase)
970                                 end
971                                 -- Create dhcp
972                                 local dhcpbase = uci:get_all("freifunk", "dhcp")
973                                 util.update(dhcpbase, uci:get_all(external, "dhcp") or {})
974                                 dhcpbase.interface = nif .. "dhcp"
975                                 dhcpbase.force = 1
976                                 uci:section("dhcp", "dhcp", nif .. "dhcp", dhcpbase)
977                                 uci:set_list("dhcp", nif .. "dhcp", "dhcp_option", "119,olsr")
978                                 -- Create firewall settings
979                                 uci:delete_all("firewall", "rule", {
980                                         src="freifunk",
981                                         proto="udp",
982                                         dest_port="53"
983                                 })
984                                 uci:section("firewall", "rule", nil, {
985                                         src="freifunk",
986                                         proto="udp",
987                                         dest_port="53",
988                                         target="ACCEPT"
989                                 })
990                                 uci:delete_all("firewall", "rule", {
991                                         src="freifunk",
992                                         proto="udp",
993                                         src_port="68",
994                                         dest_port="67"
995                                 })
996                                 uci:section("firewall", "rule", nil, {
997                                         src="freifunk",
998                                         proto="udp",
999                                         src_port="68",
1000                                         dest_port="67",
1001                                         target="ACCEPT"
1002                                 })
1003                                 uci:delete_all("firewall", "rule", {
1004                                         src="freifunk",
1005                                         proto="tcp",
1006                                         dest_port="8082",
1007                                 })
1008                                 uci:section("firewall", "rule", nil, {
1009                                         src="freifunk",
1010                                         proto="tcp",
1011                                         dest_port="8082",
1012                                         target="ACCEPT"
1013                                 })
1014                                 -- Register splash
1015                                 uci:section("luci_splash", "iface", nil, {network=nif.."dhcp", zone="freifunk"})
1016                                 uci:save("luci_splash")
1017                                 -- Make sure that luci_splash is enabled
1018                                 sys.init.enable("luci_splash")
1019                         end
1020                 else
1021                         -- Delete old splash
1022                         uci:delete_all("luci_splash", "iface", {network=device.."dhcp", zone="freifunk"})
1023                 end
1024                 --Write Ad-Hoc wifi section after AP wifi section
1025                 uci:section("wireless", "wifi-iface", nil, ifconfig)
1026                 uci:save("network")
1027                 uci:save("wireless")
1028                 uci:save("network")
1029                 uci:save("firewall")
1030                 uci:save("dhcp")
1031         end)
1032         -- Create wired ip and firewall config
1033         uci:foreach("network", "interface",
1034                 function(sec)
1035                 local device = sec[".name"]
1036                 if not luci.http.formvalue("cbid.ffwizward.1.device_" .. device) then
1037                         return
1038                 end
1039                 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
1040                         local node_ip
1041                         node_ip = luci.http.formvalue("cbid.ffwizward.1.meship_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.meship_" .. device))
1042                         if has_ipv6 then
1043                                 node_ip6 = luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device) and ip.IPv6(luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device))
1044                         end
1045                         if not node_ip or not network or not network:contains(node_ip) then
1046                                 meship.tag_missing[section] = true
1047                                 node_ip = nil
1048                                 return
1049                         end
1050                         -- Cleanup
1051                         tools.firewall_zone_remove_interface(device, device)
1052                         uci:delete_all("firewall","zone", {name=device})
1053                         uci:delete_all("firewall","forwarding", {src=device})
1054                         uci:delete_all("firewall","forwarding", {dest=device})
1055                         uci:delete("network", device .. "dhcp")
1056                         -- Delete old dhcp
1057                         uci:delete("dhcp", device)
1058                         uci:delete("dhcp", device .. "dhcp")
1059                         -- Delete old splash
1060                         uci:delete_all("luci_splash", "iface", {network=device.."dhcp", zone="freifunk"})
1061                         if has_radvd then
1062                                 uci:delete_all("radvd", "interface", {interface=device.."dhcp"})
1063                                 uci:delete_all("radvd", "interface", {interface=device})
1064                                 uci:delete_all("radvd", "prefix", {interface=device.."dhcp"})
1065                                 uci:delete_all("radvd", "prefix", {interface=device})
1066                         end
1067                         -- New Config
1068                         local netconfig = uci:get_all("freifunk", "interface")
1069                         util.update(netconfig, uci:get_all(external, "interface") or {})
1070                         netconfig.proto = "static"
1071                         netconfig.ipaddr = node_ip:string()
1072                         if has_ipv6 then
1073                                 netconfig.ip6addr = node_ip6:string()
1074                         end
1075                         uci:section("network", "interface", device, netconfig)
1076                         uci:save("network")
1077                         if has_radvd then
1078                                 uci:section("radvd", "interface", nil, {
1079                                         interface          =device,
1080                                         AdvSendAdvert      =1,
1081                                         AdvManagedFlag     =0,
1082                                         AdvOtherConfigFlag =0,
1083                                         ignore             =0
1084                                 })
1085                                 uci:section("radvd", "prefix", nil, {
1086                                         interface          =device,
1087                                         AdvOnLink          =1,
1088                                         AdvAutonomous      =1,
1089                                         AdvRouterAddr      =0,
1090                                         ignore             =0,
1091                                 })
1092                                 uci:save("radvd")
1093                         end
1094                         local new_hostname = node_ip:string():gsub("%.", "-")
1095                         uci:set("freifunk", "wizard", "hostname", new_hostname)
1096                         uci:save("freifunk")
1097                         tools.firewall_zone_add_interface("freifunk", device)
1098                         uci:save("firewall")
1099                         -- Write new olsrv4 interface
1100                         local olsrifbase = uci:get_all("freifunk", "olsr_interface")
1101                         util.update(olsrifbase, uci:get_all(external, "olsr_interface") or {})
1102                         olsrifbase.interface = device
1103                         olsrifbase.ignore    = "0"
1104                         uci:section("olsrd", "Interface", nil, olsrifbase)
1105                         olsrifbase.Mode = 'ether'
1106                         -- Collect MESH DHCP IP NET
1107                         local client = luci.http.formvalue("cbid.ffwizward.1.client_" .. device)
1108                         if client then
1109                                 local dhcpmeshnet = luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device))
1110                                 local ifacelist = uci:get_list("manager", "heartbeat", "interface") or {}
1111                                 table.insert(ifacelist,device .. "dhcp")
1112                                 uci:set_list("manager", "heartbeat", "interface", ifacelist)
1113                                 uci:save("manager")
1114                                 if dhcpmeshnet then
1115                                         if not dhcpmeshnet:minhost() or not dhcpmeshnet:mask() then
1116                                                 dhcpmesh.tag_missing[section] = true
1117                                                 dhcpmeshnet = nil
1118                                                 return
1119                                         end
1120                                         dhcp_ip = dhcpmeshnet:minhost():string()
1121                                         dhcp_mask = dhcpmeshnet:mask():string()
1122                                         dhcp_network = dhcpmeshnet:network():string()
1123                                         uci:section("olsrd", "Hna4", nil, {
1124                                                 netmask  = dhcp_mask,
1125                                                 netaddr  = dhcp_network
1126                                         })
1127                                         uci:foreach("olsrd", "LoadPlugin",
1128                                                 function(s)             
1129                                                         if s.library == "olsrd_p2pd.so.0.1.0" then
1130                                                                 uci:set("olsrd", s['.name'], "ignore", "0")
1131                                                                 local nonolsr = uci:get("olsrd", s['.name'], "NonOlsrIf") or ""
1132                                                                 uci:set("olsrd", s['.name'], "NonOlsrIf", device .." ".. nonolsr)
1133                                                         end
1134                                                 end)
1135                                 else
1136                                         local subnet_prefix = tonumber(uci:get("freifunk", community, "splash_prefix")) or 27
1137                                         local pool_network = uci:get("freifunk", community, "splash_network") or "10.104.0.0/16"
1138                                         local pool = luci.ip.IPv4(pool_network)
1139                                         local ip = tostring(node_ip)
1140                                         if pool and ip then
1141                                                 local hosts_per_subnet = 2^(32 - subnet_prefix)
1142                                                 local number_of_subnets = (2^pool:prefix())/hosts_per_subnet
1143                                                 local seed1, seed2 = ip:match("(%d+)%.(%d+)$")
1144                                                 if seed1 and seed2 then
1145                                                         math.randomseed(seed1 * seed2)
1146                                                 end
1147                                                 local subnet = pool:add(hosts_per_subnet * math.random(number_of_subnets))
1148                                                 dhcp_ip = subnet:network(subnet_prefix):add(1):string()
1149                                                 dhcp_mask = subnet:mask(subnet_prefix):string()
1150                                         end
1151                                 end
1152                                 if dhcp_ip and dhcp_mask then
1153                                         -- Create alias
1154                                         local aliasbase = uci:get_all("freifunk", "alias")
1155                                         util.update(aliasbase, uci:get_all(external, "alias") or {})
1156                                         aliasbase.interface = device
1157                                         aliasbase.ipaddr = dhcp_ip
1158                                         aliasbase.netmask = dhcp_mask
1159                                         aliasbase.proto = "static"
1160                                         uci:section("network", "alias", device .. "dhcp", aliasbase)
1161                                         -- Create dhcp
1162                                         local dhcpbase = uci:get_all("freifunk", "dhcp")
1163                                         util.update(dhcpbase, uci:get_all(external, "dhcp") or {})
1164                                         dhcpbase.interface = device .. "dhcp"
1165                                         dhcpbase.force = 1
1166                                         uci:section("dhcp", "dhcp", device .. "dhcp", dhcpbase)
1167                                         uci:set_list("dhcp", device .. "dhcp", "dhcp_option", "119,olsr")
1168                                         -- Create firewall settings
1169                                         uci:delete_all("firewall", "rule", {
1170                                                 src="freifunk",
1171                                                 proto="udp",
1172                                                 dest_port="53"
1173                                         })
1174                                         uci:section("firewall", "rule", nil, {
1175                                                 src="freifunk",
1176                                                 proto="udp",
1177                                                 dest_port="53",
1178                                                 target="ACCEPT"
1179                                         })
1180                                         uci:delete_all("firewall", "rule", {
1181                                                 src="freifunk",
1182                                                 proto="udp",
1183                                                 src_port="68",
1184                                                 dest_port="67"
1185                                         })
1186                                         uci:section("firewall", "rule", nil, {
1187                                                 src="freifunk",
1188                                                 proto="udp",
1189                                                 src_port="68",
1190                                                 dest_port="67",
1191                                                 target="ACCEPT"
1192                                         })
1193                                         uci:delete_all("firewall", "rule", {
1194                                                 src="freifunk",
1195                                                 proto="tcp",
1196                                                 dest_port="8082",
1197                                         })
1198                                         uci:section("firewall", "rule", nil, {
1199                                                 src="freifunk",
1200                                                 proto="tcp",
1201                                                 dest_port="8082",
1202                                                 target="ACCEPT"
1203                                         })
1204                                         -- Register splash
1205                                         uci:section("luci_splash", "iface", nil, {network=device.."dhcp", zone="freifunk"})
1206                                         uci:save("luci_splash")
1207                                         -- Make sure that luci_splash is enabled
1208                                         sys.init.enable("luci_splash")
1209                                 end
1210                         end
1211                         uci:save("wireless")
1212                         uci:save("network")
1213                         uci:save("firewall")
1214                         uci:save("dhcp")
1215                 end
1216         end)
1217         --enable radvd
1218         if has_radvd then
1219                 sys.init.enable("radvd")
1220         end
1221         -- Enforce firewall include
1222         local has_include = false
1223         uci:foreach("firewall", "include",
1224                 function(section)
1225                         if section.path == "/etc/firewall.freifunk" then
1226                                 has_include = true
1227                         end
1228                 end)
1229
1230         if not has_include then
1231                 uci:section("firewall", "include", nil,
1232                         { path = "/etc/firewall.freifunk" })
1233         end
1234         -- Allow state: invalid packets
1235         uci:foreach("firewall", "defaults",
1236                 function(section)
1237                         uci:set("firewall", section[".name"], "drop_invalid", "0")
1238                 end)
1239
1240         -- Prepare advanced config
1241         local has_advanced = false
1242         uci:foreach("firewall", "advanced",
1243                 function(section) has_advanced = true end)
1244
1245         if not has_advanced then
1246                 uci:section("firewall", "advanced", nil,
1247                         { tcp_ecn = "0", ip_conntrack_max = "8192", tcp_westwood = "1" })
1248         end
1249         uci:save("wireless")
1250         uci:save("network")
1251         uci:save("firewall")
1252         uci:save("dhcp")
1253
1254         local new_hostname = uci:get("freifunk", "wizard", "hostname")
1255         local old_hostname = sys.hostname()
1256
1257         local dhcphb = hb:formvalue(section)
1258         if dhcphb then
1259                 uci:set("manager", "heartbeat", "enabled", "1")
1260                 -- Make sure that heartbeat is enabled
1261                 sys.init.enable("machash")
1262
1263         else
1264                 uci:set("manager", "heartbeat", "enabled", "0")
1265                 -- Make sure that heartbeat is enabled
1266                 sys.init.disable("machash")
1267         end
1268         uci:save("manager")
1269
1270         local custom_hostname = hostname:formvalue(section)
1271         uci:foreach("system", "system",
1272                 function(s)
1273                         -- Make crond silent
1274                         uci:set("system", s['.name'], "cronloglevel", "10")
1275                         -- Make set timzone and zonename
1276                         uci:set("system", s['.name'], "zonename", "Europe/Berlin")
1277                         uci:set("system", s['.name'], "timezone", 'CET-1CEST,M3.5.0,M10.5.0/3')
1278                         -- Set hostname
1279                         if custom_hostname then
1280                                 uci:set("system", s['.name'], "hostname", custom_hostname)
1281                                 sys.hostname(custom_hostname)
1282                         else
1283                                 if new_hostname then
1284                                         if old_hostname == "OpenWrt" or old_hostname:match("^%d+-%d+-%d+-%d+$") then
1285                                                 uci:set("system", s['.name'], "hostname", new_hostname)
1286                                                 sys.hostname(new_hostname)
1287                                         end
1288                                 end
1289                         end
1290                 end)
1291
1292         -- Create time rdate_servers
1293         local rdate = uci:get_all("freifunk", "time")
1294         uci:delete_all("system", "time")
1295         uci:section("system", "time", "rdate_servers", rdate)
1296         rdate.server = rdate.rdate_servers
1297         rdate.rdate_servers = ""
1298         uci:delete_all("system", "rdate", nil)
1299         uci:section("system", "rdate", nil, rdate)
1300         uci:save("system")
1301
1302         -- Create http splash port 8082
1303         uci:set_list("uhttpd","main","listen_http",{"80"})
1304         uci:set_list("uhttpd","main","listen_https",{"443"})
1305         uci:save("uhttpd")
1306
1307         -- Read geos
1308         local latval = tonumber(lat:formvalue(section))
1309         local lonval = tonumber(lon:formvalue(section))
1310
1311         -- Save latlon to system too
1312         if latval and lonval then
1313                 uci:foreach("system", "system", function(s)
1314                         uci:set("system", s[".name"], "latlon",string.format("%.15f %.15f", latval, lonval))
1315                         uci:set("system", s[".name"], "latitude",string.format("%.15f", latval))
1316                         uci:set("system", s[".name"], "longitude",string.format("%.15f", lonval))
1317                 end)
1318         else
1319                 uci:foreach("system", "system", function(s)
1320                         uci:delete("system", s[".name"], "latlon")
1321                         uci:delete("system", s[".name"], "latitude")
1322                         uci:delete("system", s[".name"], "longitude")
1323                 end)
1324         end
1325         -- Delete old watchdog settings
1326         uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_watchdog.so.0.1"})
1327         -- Write new watchdog settings
1328         uci:section("olsrd", "LoadPlugin", nil, {
1329                 library  = "olsrd_watchdog.so.0.1",
1330                 file     = "/var/run/olsrd.watchdog",
1331                 interval = "30"
1332         })
1333
1334         -- Delete old nameservice settings
1335         uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_nameservice.so.0.3"})
1336         -- Write new nameservice settings
1337         uci:section("olsrd", "LoadPlugin", nil, {
1338                 library     = "olsrd_nameservice.so.0.3",
1339                 suffix      = "." .. suffix ,
1340                 hosts_file  = "/var/etc/hosts.olsr",
1341                 latlon_file = "/var/run/latlon.js",
1342                 lat         = latval and string.format("%.15f", latval) or "",
1343                 lon         = lonval and string.format("%.15f", lonval) or "",
1344                 services_file = "/var/etc/services.olsr"
1345         })
1346
1347         -- Import hosts and set domain
1348         uci:foreach("dhcp", "dnsmasq", function(s)
1349                 uci:set_list("dhcp", s[".name"], "addnhosts", "/var/etc/hosts.olsr")
1350                 uci:set("dhcp", s[".name"], "local", "/" .. suffix .. "/")
1351                 uci:set("dhcp", s[".name"], "domain", suffix)
1352         end)
1353
1354         -- Make sure that OLSR is enabled
1355         sys.init.enable("olsrd")
1356
1357         uci:save("olsrd")
1358         uci:save("dhcp")
1359         -- Import hosts and set domain
1360         uci:foreach("dhcp", "dnsmasq", function(s)
1361                 uci:set_list("dhcp", s[".name"], "addnhosts", "/var/etc/hosts.olsr")
1362         end)
1363
1364         if has_ipv6 then
1365                 uci:foreach("dhcp", "dnsmasq", function(s)
1366                         uci:set_list("dhcp", s[".name"], "addnhosts", "/var/etc/hosts.olsr.ipv6")
1367                 end)
1368         end
1369
1370
1371         uci:save("dhcp")
1372
1373         -- Internet sharing
1374         local share_value = share:formvalue(section)
1375         if share_value == "1" then
1376                 uci:set("freifunk", "wizard", "netconfig", "1")
1377                 uci:section("firewall", "forwarding", nil, {src="freifunk", dest="wan"})
1378
1379                 if has_autoipv6 then
1380                         -- Set autoipv6 tunnel mode
1381                         uci:set("autoipv6", "olsr_node", "enable", "0")
1382                         uci:set("autoipv6", "tunnel", "enable", "1")
1383                         uci:save("autoipv6")
1384                 end
1385
1386                 -- Delete/Disable gateway plugin
1387                 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_dyn_gw.so.0.5"})
1388                 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_dyn_gw_plain.so.0.4"})
1389                 -- Enable gateway_plain plugin
1390                 uci:section("olsrd", "LoadPlugin", nil, {library="olsrd_dyn_gw_plain.so.0.4"})
1391                 sys.exec("chmod +x /etc/init.d/freifunk-p2pblock")
1392                 sys.init.enable("freifunk-p2pblock")
1393                 sys.init.enable("qos")
1394                 sys.exec('grep wan /etc/crontabs/root >/dev/null || echo "0 6 * * *     ifup wan" >> /etc/crontabs/root')
1395
1396                 if wansec:formvalue(section) == "1" then
1397                         uci:foreach("firewall", "zone",
1398                                 function(s)             
1399                                         if s.name == "wan" then
1400                                                 uci:set("firewall", s['.name'], "local_restrict", "1")
1401                                                 return false
1402                                         end
1403                                 end)
1404                 end
1405         else
1406                 uci:set("freifunk", "wizard", "netconfig", "0")
1407                 uci:save("freifunk")
1408                 if has_autoipv6 then
1409                         -- Set autoipv6 olsrd mode
1410                         uci:set("autoipv6", "olsr_node", "enable", "1")
1411                         uci:set("autoipv6", "tunnel", "enable", "0")
1412                         uci:save("autoipv6")
1413                 end
1414                 -- Delete gateway plugins
1415                 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_dyn_gw.so.0.5"})
1416                 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_dyn_gw_plain.so.0.4"})
1417                 -- Disable gateway_plain plugin
1418                 uci:section("olsrd", "LoadPlugin", nil, {
1419                         library     = "olsrd_dyn_gw_plain.so.0.4",
1420                         ignore      = 1,
1421                 })
1422                 sys.init.disable("freifunk-p2pblock")
1423                 sys.init.disable("qos")
1424                 sys.exec("chmod -x /etc/init.d/freifunk-p2pblock")
1425                 uci:delete_all("firewall", "forwarding", {src="freifunk", dest="wan"})
1426                 uci:foreach("firewall", "zone",
1427                         function(s)             
1428                                 if s.name == "wan" then
1429                                         uci:delete("firewall", s['.name'], "local_restrict")
1430                                         return false
1431                                 end
1432                         end)
1433         end
1434         -- Write gvpn dummy interface
1435         if has_l2gvpn then
1436                 if gvpn then
1437                         local vpn = gvpn:formvalue(section)
1438                         if vpn then
1439                                 uci:delete_all("l2gvpn", "l2gvpn")
1440                                 uci:delete_all("l2gvpn", "node")
1441                                 uci:delete_all("l2gvpn", "supernode")
1442                                 -- Write olsr tunnel interface options
1443                                 local olsr_gvpnifbase = uci:get_all("freifunk", "olsr_gvpninterface")
1444                                 util.update(olsr_gvpnifbase, uci:get_all(external, "olsr_gvpninterface") or {})
1445                                 uci:section("olsrd", "Interface", nil, olsr_gvpnifbase)
1446                                 local vpnip = gvpnip:formvalue(section)
1447                                 local gvpnif = uci:get_all("freifunk", "gvpn_node")
1448                                 util.update(gvpnif, uci:get_all(external, "gvpn_node") or {})
1449                                 if gvpnif and gvpnif.tundev and vpnip then
1450                                         uci:section("network", "interface", gvpnif.tundev, {
1451                                                 ifname  =gvpnif.tundev ,
1452                                                 proto   ="static" ,
1453                                                 ipaddr  =vpnip ,
1454                                                 netmask =gvpnif.subnet or "255.255.255.192" ,
1455                                         })
1456                                         gvpnif.ip=""
1457                                         gvpnif.subnet=""
1458                                         gvpnif.up=""
1459                                         gvpnif.down=""
1460                                         gvpnif.mac="00:00:48:"..string.format("%X",string.gsub( vpnip, ".*%." , "" ))..":00:00"
1461                                         tools.firewall_zone_add_interface("freifunk", gvpnif.tundev)
1462                                         uci:section("l2gvpn", "node" , gvpnif.community , gvpnif)
1463                                         uci:save("network")
1464                                         uci:save("l2gvpn")
1465                                         uci:save("firewall")
1466                                         uci:save("olsrd")
1467                                         sys.init.enable("l2gvpn")
1468                                 end
1469                         else
1470                                 -- Disable l2gvpn
1471                                 sys.exec("/etc/init.d/l2gvpn stop")
1472                                 sys.init.disable("l2gvpn")
1473                         end
1474                 end
1475         end
1476
1477         uci:save("freifunk")
1478         uci:save("firewall")
1479         uci:save("olsrd")
1480         uci:save("system")
1481 end
1482
1483 return f
1484