luci-mod-admin-full/mini: replace Wifi with Wireless in menus
[project/luci.git] / modules / luci-mod-admin-full / luasrc / controller / admin / network.lua
1 -- Copyright 2008 Steven Barth <steven@midlink.org>
2 -- Copyright 2011-2015 Jo-Philipp Wich <jow@openwrt.org>
3 -- Licensed to the public under the Apache License 2.0.
4
5 module("luci.controller.admin.network", package.seeall)
6
7 function index()
8         local uci = require("luci.model.uci").cursor()
9         local page
10
11         page = node("admin", "network")
12         page.target = firstchild()
13         page.title  = _("Network")
14         page.order  = 50
15         page.index  = true
16
17 --      if page.inreq then
18                 local has_switch = false
19
20                 uci:foreach("network", "switch",
21                         function(s)
22                                 has_switch = true
23                                 return false
24                         end)
25
26                 if has_switch then
27                         page  = node("admin", "network", "vlan")
28                         page.target = cbi("admin_network/vlan")
29                         page.title  = _("Switch")
30                         page.order  = 20
31
32                         page = entry({"admin", "network", "switch_status"}, call("switch_status"), nil)
33                         page.leaf = true
34                 end
35
36
37                 local has_wifi = false
38
39                 uci:foreach("wireless", "wifi-device",
40                         function(s)
41                                 has_wifi = true
42                                 return false
43                         end)
44
45                 if has_wifi then
46                         page = entry({"admin", "network", "wireless_join"}, post("wifi_join"), nil)
47                         page.leaf = true
48
49                         page = entry({"admin", "network", "wireless_add"}, post("wifi_add"), nil)
50                         page.leaf = true
51
52                         page = entry({"admin", "network", "wireless_delete"}, post("wifi_delete"), nil)
53                         page.leaf = true
54
55                         page = entry({"admin", "network", "wireless_status"}, call("wifi_status"), nil)
56                         page.leaf = true
57
58                         page = entry({"admin", "network", "wireless_reconnect"}, post("wifi_reconnect"), nil)
59                         page.leaf = true
60
61                         page = entry({"admin", "network", "wireless_shutdown"}, post("wifi_shutdown"), nil)
62                         page.leaf = true
63
64                         page = entry({"admin", "network", "wireless"}, arcombine(template("admin_network/wifi_overview"), cbi("admin_network/wifi")), _("Wireless"), 15)
65                         page.leaf = true
66                         page.subindex = true
67
68                         if page.inreq then
69                                 local wdev
70                                 local net = require "luci.model.network".init(uci)
71                                 for _, wdev in ipairs(net:get_wifidevs()) do
72                                         local wnet
73                                         for _, wnet in ipairs(wdev:get_wifinets()) do
74                                                 entry(
75                                                         {"admin", "network", "wireless", wnet:id()},
76                                                         alias("admin", "network", "wireless"),
77                                                         wdev:name() .. ": " .. wnet:shortname()
78                                                 )
79                                         end
80                                 end
81                         end
82                 end
83
84
85                 page = entry({"admin", "network", "iface_add"}, cbi("admin_network/iface_add"), nil)
86                 page.leaf = true
87
88                 page = entry({"admin", "network", "iface_delete"}, post("iface_delete"), nil)
89                 page.leaf = true
90
91                 page = entry({"admin", "network", "iface_status"}, call("iface_status"), nil)
92                 page.leaf = true
93
94                 page = entry({"admin", "network", "iface_reconnect"}, post("iface_reconnect"), nil)
95                 page.leaf = true
96
97                 page = entry({"admin", "network", "iface_shutdown"}, post("iface_shutdown"), nil)
98                 page.leaf = true
99
100                 page = entry({"admin", "network", "network"}, arcombine(cbi("admin_network/network"), cbi("admin_network/ifaces")), _("Interfaces"), 10)
101                 page.leaf   = true
102                 page.subindex = true
103
104                 if page.inreq then
105                         uci:foreach("network", "interface",
106                                 function (section)
107                                         local ifc = section[".name"]
108                                         if ifc ~= "loopback" then
109                                                 entry({"admin", "network", "network", ifc},
110                                                 true, ifc:upper())
111                                         end
112                                 end)
113                 end
114
115
116                 if nixio.fs.access("/etc/config/dhcp") then
117                         page = node("admin", "network", "dhcp")
118                         page.target = cbi("admin_network/dhcp")
119                         page.title  = _("DHCP and DNS")
120                         page.order  = 30
121
122                         page = entry({"admin", "network", "dhcplease_status"}, call("lease_status"), nil)
123                         page.leaf = true
124
125                         page = node("admin", "network", "hosts")
126                         page.target = cbi("admin_network/hosts")
127                         page.title  = _("Hostnames")
128                         page.order  = 40
129                 end
130
131                 page  = node("admin", "network", "routes")
132                 page.target = cbi("admin_network/routes")
133                 page.title  = _("Static Routes")
134                 page.order  = 50
135
136                 page = node("admin", "network", "diagnostics")
137                 page.target = template("admin_network/diagnostics")
138                 page.title  = _("Diagnostics")
139                 page.order  = 60
140
141                 page = entry({"admin", "network", "diag_ping"}, post("diag_ping"), nil)
142                 page.leaf = true
143
144                 page = entry({"admin", "network", "diag_nslookup"}, post("diag_nslookup"), nil)
145                 page.leaf = true
146
147                 page = entry({"admin", "network", "diag_traceroute"}, post("diag_traceroute"), nil)
148                 page.leaf = true
149
150                 page = entry({"admin", "network", "diag_ping6"}, post("diag_ping6"), nil)
151                 page.leaf = true
152
153                 page = entry({"admin", "network", "diag_traceroute6"}, post("diag_traceroute6"), nil)
154                 page.leaf = true
155 --      end
156 end
157
158 function wifi_join()
159         local tpl  = require "luci.template"
160         local http = require "luci.http"
161         local dev  = http.formvalue("device")
162         local ssid = http.formvalue("join")
163
164         if dev and ssid then
165                 local cancel = (http.formvalue("cancel") or http.formvalue("cbi.cancel"))
166                 if not cancel then
167                         local cbi = require "luci.cbi"
168                         local map = luci.cbi.load("admin_network/wifi_add")[1]
169
170                         if map:parse() ~= cbi.FORM_DONE then
171                                 tpl.render("header")
172                                 map:render()
173                                 tpl.render("footer")
174                         end
175
176                         return
177                 end
178         end
179
180         tpl.render("admin_network/wifi_join")
181 end
182
183 function wifi_add()
184         local dev = luci.http.formvalue("device")
185         local ntm = require "luci.model.network".init()
186
187         dev = dev and ntm:get_wifidev(dev)
188
189         if dev then
190                 local net = dev:add_wifinet({
191                         mode       = "ap",
192                         ssid       = "OpenWrt",
193                         encryption = "none"
194                 })
195
196                 ntm:save("wireless")
197                 luci.http.redirect(net:adminlink())
198         end
199 end
200
201 function wifi_delete(network)
202         local ntm = require "luci.model.network".init()
203         local wnet = ntm:get_wifinet(network)
204         if wnet then
205                 local dev = wnet:get_device()
206                 local nets = wnet:get_networks()
207                 if dev then
208                         ntm:del_wifinet(network)
209                         ntm:commit("wireless")
210                         local _, net
211                         for _, net in ipairs(nets) do
212                                 if net:is_empty() then
213                                         ntm:del_network(net:name())
214                                         ntm:commit("network")
215                                 end
216                         end
217                         luci.sys.call("env -i /bin/ubus call network reload >/dev/null 2>/dev/null")
218                 end
219         end
220
221         luci.http.redirect(luci.dispatcher.build_url("admin/network/wireless"))
222 end
223
224 function iface_status(ifaces)
225         local netm = require "luci.model.network".init()
226         local rv   = { }
227
228         local iface
229         for iface in ifaces:gmatch("[%w%.%-_]+") do
230                 local net = netm:get_network(iface)
231                 local device = net and net:get_interface()
232                 if device then
233                         local data = {
234                                 id         = iface,
235                                 proto      = net:proto(),
236                                 uptime     = net:uptime(),
237                                 gwaddr     = net:gwaddr(),
238                                 ipaddrs    = net:ipaddrs(),
239                                 ip6addrs   = net:ip6addrs(),
240                                 dnsaddrs   = net:dnsaddrs(),
241                                 name       = device:shortname(),
242                                 type       = device:type(),
243                                 ifname     = device:name(),
244                                 macaddr    = device:mac(),
245                                 is_up      = device:is_up(),
246                                 rx_bytes   = device:rx_bytes(),
247                                 tx_bytes   = device:tx_bytes(),
248                                 rx_packets = device:rx_packets(),
249                                 tx_packets = device:tx_packets(),
250
251                                 subdevices = { }
252                         }
253
254                         for _, device in ipairs(net:get_interfaces() or {}) do
255                                 data.subdevices[#data.subdevices+1] = {
256                                         name       = device:shortname(),
257                                         type       = device:type(),
258                                         ifname     = device:name(),
259                                         macaddr    = device:mac(),
260                                         macaddr    = device:mac(),
261                                         is_up      = device:is_up(),
262                                         rx_bytes   = device:rx_bytes(),
263                                         tx_bytes   = device:tx_bytes(),
264                                         rx_packets = device:rx_packets(),
265                                         tx_packets = device:tx_packets(),
266                                 }
267                         end
268
269                         rv[#rv+1] = data
270                 else
271                         rv[#rv+1] = {
272                                 id   = iface,
273                                 name = iface,
274                                 type = "ethernet"
275                         }
276                 end
277         end
278
279         if #rv > 0 then
280                 luci.http.prepare_content("application/json")
281                 luci.http.write_json(rv)
282                 return
283         end
284
285         luci.http.status(404, "No such device")
286 end
287
288 function iface_reconnect(iface)
289         local netmd = require "luci.model.network".init()
290         local net = netmd:get_network(iface)
291         if net then
292                 luci.sys.call("env -i /sbin/ifup %q >/dev/null 2>/dev/null" % iface)
293                 luci.http.status(200, "Reconnected")
294                 return
295         end
296
297         luci.http.status(404, "No such interface")
298 end
299
300 function iface_shutdown(iface)
301         local netmd = require "luci.model.network".init()
302         local net = netmd:get_network(iface)
303         if net then
304                 luci.sys.call("env -i /sbin/ifdown %q >/dev/null 2>/dev/null" % iface)
305                 luci.http.status(200, "Shutdown")
306                 return
307         end
308
309         luci.http.status(404, "No such interface")
310 end
311
312 function iface_delete(iface)
313         local netmd = require "luci.model.network".init()
314         local net = netmd:del_network(iface)
315         if net then
316                 luci.sys.call("env -i /sbin/ifdown %q >/dev/null 2>/dev/null" % iface)
317                 luci.http.redirect(luci.dispatcher.build_url("admin/network/network"))
318                 netmd:commit("network")
319                 netmd:commit("wireless")
320                 return
321         end
322
323         luci.http.status(404, "No such interface")
324 end
325
326 function wifi_status(devs)
327         local s    = require "luci.tools.status"
328         local rv   = { }
329
330         local dev
331         for dev in devs:gmatch("[%w%.%-]+") do
332                 rv[#rv+1] = s.wifi_network(dev)
333         end
334
335         if #rv > 0 then
336                 luci.http.prepare_content("application/json")
337                 luci.http.write_json(rv)
338                 return
339         end
340
341         luci.http.status(404, "No such device")
342 end
343
344 local function wifi_reconnect_shutdown(shutdown, wnet)
345         local netmd = require "luci.model.network".init()
346         local net = netmd:get_wifinet(wnet)
347         local dev = net:get_device()
348         if dev and net then
349                 dev:set("disabled", nil)
350                 net:set("disabled", shutdown and 1 or nil)
351                 netmd:commit("wireless")
352
353                 luci.sys.call("env -i /bin/ubus call network reload >/dev/null 2>/dev/null")
354                 luci.http.status(200, shutdown and "Shutdown" or "Reconnected")
355
356                 return
357         end
358
359         luci.http.status(404, "No such radio")
360 end
361
362 function wifi_reconnect(wnet)
363         wifi_reconnect_shutdown(false, wnet)
364 end
365
366 function wifi_shutdown(wnet)
367         wifi_reconnect_shutdown(true, wnet)
368 end
369
370 function lease_status()
371         local s = require "luci.tools.status"
372
373         luci.http.prepare_content("application/json")
374         luci.http.write('[')
375         luci.http.write_json(s.dhcp_leases())
376         luci.http.write(',')
377         luci.http.write_json(s.dhcp6_leases())
378         luci.http.write(']')
379 end
380
381 function switch_status(switches)
382         local s = require "luci.tools.status"
383
384         luci.http.prepare_content("application/json")
385         luci.http.write_json(s.switch_status(switches))
386 end
387
388 function diag_command(cmd, addr)
389         if addr and addr:match("^[a-zA-Z0-9%-%.:_]+$") then
390                 luci.http.prepare_content("text/plain")
391
392                 local util = io.popen(cmd % addr)
393                 if util then
394                         while true do
395                                 local ln = util:read("*l")
396                                 if not ln then break end
397                                 luci.http.write(ln)
398                                 luci.http.write("\n")
399                         end
400
401                         util:close()
402                 end
403
404                 return
405         end
406
407         luci.http.status(500, "Bad address")
408 end
409
410 function diag_ping(addr)
411         diag_command("ping -c 5 -W 1 %q 2>&1", addr)
412 end
413
414 function diag_traceroute(addr)
415         diag_command("traceroute -q 1 -w 1 -n %q 2>&1", addr)
416 end
417
418 function diag_nslookup(addr)
419         diag_command("nslookup %q 2>&1", addr)
420 end
421
422 function diag_ping6(addr)
423         diag_command("ping6 -c 5 %q 2>&1", addr)
424 end
425
426 function diag_traceroute6(addr)
427         diag_command("traceroute6 -q 1 -w 2 -n %q 2>&1", addr)
428 end