1 -- Copyright 2008 Steven Barth <steven@midlink.org>
2 -- Copyright 2011-2018 Jo-Philipp Wich <jo@mein.io>
3 -- Licensed to the public under the Apache License 2.0.
5 module("luci.controller.admin.network", package.seeall)
8 local uci = require("luci.model.uci").cursor()
12 local has_switch = false
14 uci:foreach("network", "switch",
21 entry({"admin", "network", "switch"}, view("network/switch"), _("Switch"), 20)
25 local has_wifi = false
27 uci:foreach("wireless", "wifi-device",
34 page = entry({"admin", "network", "wireless_status"}, call("wifi_status"), nil)
37 page = entry({"admin", "network", "wireless_reconnect"}, post("wifi_reconnect"), nil)
40 page = entry({"admin", "network", "wireless"}, view("network/wireless"), _('Wireless'), 15)
45 page = entry({"admin", "network", "iface_status"}, call("iface_status"), nil)
48 page = entry({"admin", "network", "iface_reconnect"}, post("iface_reconnect"), nil)
51 page = entry({"admin", "network", "iface_down"}, post("iface_down"), nil)
54 page = entry({"admin", "network", "network"}, view("network/interfaces"), _("Interfaces"), 10)
59 if nixio.fs.access("/etc/config/dhcp") then
60 page = node("admin", "network", "dhcp")
61 page.target = view("network/dhcp")
62 page.title = _("DHCP and DNS")
65 page = node("admin", "network", "hosts")
66 page.target = view("network/hosts")
67 page.title = _("Hostnames")
71 page = node("admin", "network", "routes")
72 page.target = view("network/routes")
73 page.title = _("Static Routes")
76 page = node("admin", "network", "diagnostics")
77 page.target = template("admin_network/diagnostics")
78 page.title = _("Diagnostics")
81 page = entry({"admin", "network", "diag_ping"}, post("diag_ping"), nil)
84 page = entry({"admin", "network", "diag_nslookup"}, post("diag_nslookup"), nil)
87 page = entry({"admin", "network", "diag_traceroute"}, post("diag_traceroute"), nil)
90 page = entry({"admin", "network", "diag_ping6"}, post("diag_ping6"), nil)
93 page = entry({"admin", "network", "diag_traceroute6"}, post("diag_traceroute6"), nil)
98 function iface_status(ifaces)
99 local netm = require "luci.model.network".init()
103 for iface in ifaces:gmatch("[%w%.%-_]+") do
104 local net = netm:get_network(iface)
105 local device = net and net:get_interface()
109 desc = net:get_i18n(),
111 uptime = net:uptime(),
112 gwaddr = net:gwaddr(),
113 ipaddrs = net:ipaddrs(),
114 ip6addrs = net:ip6addrs(),
115 dnsaddrs = net:dnsaddrs(),
116 ip6prefix = net:ip6prefix(),
117 errors = net:errors(),
118 name = device:shortname(),
119 type = device:type(),
120 typename = device:get_type_i18n(),
121 ifname = device:name(),
122 macaddr = device:mac(),
123 is_up = net:is_up() and device:is_up(),
124 is_alias = net:is_alias(),
125 is_dynamic = net:is_dynamic(),
126 is_auto = net:is_auto(),
127 rx_bytes = device:rx_bytes(),
128 tx_bytes = device:tx_bytes(),
129 rx_packets = device:rx_packets(),
130 tx_packets = device:tx_packets(),
135 for _, device in ipairs(net:get_interfaces() or {}) do
136 data.subdevices[#data.subdevices+1] = {
137 name = device:shortname(),
138 type = device:type(),
139 typename = device:get_type_i18n(),
140 ifname = device:name(),
141 macaddr = device:mac(),
142 is_up = device:is_up(),
143 rx_bytes = device:rx_bytes(),
144 tx_bytes = device:tx_bytes(),
145 rx_packets = device:rx_packets(),
146 tx_packets = device:tx_packets(),
161 luci.http.prepare_content("application/json")
162 luci.http.write_json(rv)
166 luci.http.status(404, "No such device")
169 function iface_reconnect(iface)
170 local netmd = require "luci.model.network".init()
171 local net = netmd:get_network(iface)
173 luci.sys.call("env -i /sbin/ifup %s >/dev/null 2>/dev/null"
174 % luci.util.shellquote(iface))
175 luci.http.status(200, "Reconnected")
179 luci.http.status(404, "No such interface")
182 local function addr2dev(addr, src)
183 local ip = require "luci.ip"
184 local route = ip.route(addr, src)
185 if not src and route and route.src then
186 route = ip.route(addr, route.src:string())
188 return route and route.dev
191 function iface_down(iface, force)
192 local netmd = require "luci.model.network".init()
193 local peer = luci.http.getenv("REMOTE_ADDR")
194 local serv = luci.http.getenv("SERVER_ADDR")
196 if force ~= "force" and serv and peer then
197 local dev = addr2dev(peer, serv)
199 local nets = netmd:get_networks()
203 for _, net in ipairs(nets) do
204 if net:contains_interface(dev) then
210 if outnet:name() == iface then
211 luci.http.status(409, "Is inbound interface")
215 local peeraddr = outnet:get("peeraddr")
216 for _, ai in ipairs(peeraddr and nixio.getaddrinfo(peeraddr) or {}) do
217 local peerdev = addr2dev(ai.address)
218 for _, net in ipairs(peerdev and nets or {}) do
219 if net:contains_interface(peerdev) and net:name() == iface then
220 luci.http.status(409, "Is inbound interface")
228 if netmd:get_network(iface) then
229 luci.sys.call("env -i /sbin/ifdown %s >/dev/null 2>/dev/null"
230 % luci.util.shellquote(iface))
231 luci.http.status(200, "Shut down")
235 luci.http.status(404, "No such interface")
238 function wifi_status(devs)
239 local s = require "luci.tools.status"
242 if type(devs) == "string" then
244 for dev in devs:gmatch("[%w%.%-]+") do
245 rv[#rv+1] = s.wifi_network(dev)
250 luci.http.prepare_content("application/json")
251 luci.http.write_json(rv)
255 luci.http.status(404, "No such device")
258 function wifi_reconnect(radio)
259 local rc = luci.sys.call("env -i /sbin/wifi up %s >/dev/null" % luci.util.shellquote(radio))
262 luci.http.status(200, "Reconnected")
264 luci.http.status(500, "Error")
268 function diag_command(cmd, addr)
269 if addr and addr:match("^[a-zA-Z0-9%-%.:_]+$") then
270 luci.http.prepare_content("text/plain")
272 local util = io.popen(cmd % luci.util.shellquote(addr))
275 local ln = util:read("*l")
276 if not ln then break end
278 luci.http.write("\n")
287 luci.http.status(500, "Bad address")
290 function diag_ping(addr)
291 diag_command("ping -c 5 -W 1 %s 2>&1", addr)
294 function diag_traceroute(addr)
295 diag_command("traceroute -q 1 -w 1 -n %s 2>&1", addr)
298 function diag_nslookup(addr)
299 diag_command("nslookup %s 2>&1", addr)
302 function diag_ping6(addr)
303 diag_command("ping6 -c 5 %s 2>&1", addr)
306 function diag_traceroute6(addr)
307 diag_command("traceroute6 -q 1 -w 2 -n %s 2>&1", addr)