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 page = node("admin", "network", "vlan")
22 page.target = cbi("admin_network/vlan")
23 page.title = _("Switch")
26 page = entry({"admin", "network", "switch_status"}, call("switch_status"), nil)
31 local has_wifi = false
33 uci:foreach("wireless", "wifi-device",
40 page = entry({"admin", "network", "wireless_status"}, call("wifi_status"), nil)
43 page = entry({"admin", "network", "wireless_reconnect"}, post("wifi_reconnect"), nil)
46 page = entry({"admin", "network", "wireless"}, view("network/wireless"), _('Wireless'), 15)
51 page = entry({"admin", "network", "iface_status"}, call("iface_status"), nil)
54 page = entry({"admin", "network", "iface_reconnect"}, post("iface_reconnect"), nil)
57 page = entry({"admin", "network", "iface_down"}, post("iface_down"), nil)
60 page = entry({"admin", "network", "network"}, view("network/interfaces"), _("Interfaces"), 10)
65 if nixio.fs.access("/etc/config/dhcp") then
66 page = node("admin", "network", "dhcp")
67 page.target = view("network/dhcp")
68 page.title = _("DHCP and DNS")
71 page = node("admin", "network", "hosts")
72 page.target = view("network/hosts")
73 page.title = _("Hostnames")
77 page = node("admin", "network", "routes")
78 page.target = view("network/routes")
79 page.title = _("Static Routes")
82 page = node("admin", "network", "diagnostics")
83 page.target = template("admin_network/diagnostics")
84 page.title = _("Diagnostics")
87 page = entry({"admin", "network", "diag_ping"}, post("diag_ping"), nil)
90 page = entry({"admin", "network", "diag_nslookup"}, post("diag_nslookup"), nil)
93 page = entry({"admin", "network", "diag_traceroute"}, post("diag_traceroute"), nil)
96 page = entry({"admin", "network", "diag_ping6"}, post("diag_ping6"), nil)
99 page = entry({"admin", "network", "diag_traceroute6"}, post("diag_traceroute6"), nil)
104 function iface_status(ifaces)
105 local netm = require "luci.model.network".init()
109 for iface in ifaces:gmatch("[%w%.%-_]+") do
110 local net = netm:get_network(iface)
111 local device = net and net:get_interface()
115 desc = net:get_i18n(),
117 uptime = net:uptime(),
118 gwaddr = net:gwaddr(),
119 ipaddrs = net:ipaddrs(),
120 ip6addrs = net:ip6addrs(),
121 dnsaddrs = net:dnsaddrs(),
122 ip6prefix = net:ip6prefix(),
123 errors = net:errors(),
124 name = device:shortname(),
125 type = device:type(),
126 typename = device:get_type_i18n(),
127 ifname = device:name(),
128 macaddr = device:mac(),
129 is_up = net:is_up() and device:is_up(),
130 is_alias = net:is_alias(),
131 is_dynamic = net:is_dynamic(),
132 is_auto = net:is_auto(),
133 rx_bytes = device:rx_bytes(),
134 tx_bytes = device:tx_bytes(),
135 rx_packets = device:rx_packets(),
136 tx_packets = device:tx_packets(),
141 for _, device in ipairs(net:get_interfaces() or {}) do
142 data.subdevices[#data.subdevices+1] = {
143 name = device:shortname(),
144 type = device:type(),
145 typename = device:get_type_i18n(),
146 ifname = device:name(),
147 macaddr = device:mac(),
148 is_up = device:is_up(),
149 rx_bytes = device:rx_bytes(),
150 tx_bytes = device:tx_bytes(),
151 rx_packets = device:rx_packets(),
152 tx_packets = device:tx_packets(),
167 luci.http.prepare_content("application/json")
168 luci.http.write_json(rv)
172 luci.http.status(404, "No such device")
175 function iface_reconnect(iface)
176 local netmd = require "luci.model.network".init()
177 local net = netmd:get_network(iface)
179 luci.sys.call("env -i /sbin/ifup %s >/dev/null 2>/dev/null"
180 % luci.util.shellquote(iface))
181 luci.http.status(200, "Reconnected")
185 luci.http.status(404, "No such interface")
188 local function addr2dev(addr, src)
189 local ip = require "luci.ip"
190 local route = ip.route(addr, src)
191 if not src and route and route.src then
192 route = ip.route(addr, route.src:string())
194 return route and route.dev
197 function iface_down(iface, force)
198 local netmd = require "luci.model.network".init()
199 local peer = luci.http.getenv("REMOTE_ADDR")
200 local serv = luci.http.getenv("SERVER_ADDR")
202 if force ~= "force" and serv and peer then
203 local dev = addr2dev(peer, serv)
205 local nets = netmd:get_networks()
209 for _, net in ipairs(nets) do
210 if net:contains_interface(dev) then
216 if outnet:name() == iface then
217 luci.http.status(409, "Is inbound interface")
221 local peeraddr = outnet:get("peeraddr")
222 for _, ai in ipairs(peeraddr and nixio.getaddrinfo(peeraddr) or {}) do
223 local peerdev = addr2dev(ai.address)
224 for _, net in ipairs(peerdev and nets or {}) do
225 if net:contains_interface(peerdev) and net:name() == iface then
226 luci.http.status(409, "Is inbound interface")
234 if netmd:get_network(iface) then
235 luci.sys.call("env -i /sbin/ifdown %s >/dev/null 2>/dev/null"
236 % luci.util.shellquote(iface))
237 luci.http.status(200, "Shut down")
241 luci.http.status(404, "No such interface")
244 function wifi_status(devs)
245 local s = require "luci.tools.status"
248 if type(devs) == "string" then
250 for dev in devs:gmatch("[%w%.%-]+") do
251 rv[#rv+1] = s.wifi_network(dev)
256 luci.http.prepare_content("application/json")
257 luci.http.write_json(rv)
261 luci.http.status(404, "No such device")
264 function wifi_reconnect(radio)
265 local rc = luci.sys.call("env -i /sbin/wifi up %s >/dev/null" % luci.util.shellquote(radio))
268 luci.http.status(200, "Reconnected")
270 luci.http.status(500, "Error")
274 function switch_status(switches)
275 local s = require "luci.tools.status"
277 luci.http.prepare_content("application/json")
278 luci.http.write_json(s.switch_status(switches))
281 function diag_command(cmd, addr)
282 if addr and addr:match("^[a-zA-Z0-9%-%.:_]+$") then
283 luci.http.prepare_content("text/plain")
285 local util = io.popen(cmd % luci.util.shellquote(addr))
288 local ln = util:read("*l")
289 if not ln then break end
291 luci.http.write("\n")
300 luci.http.status(500, "Bad address")
303 function diag_ping(addr)
304 diag_command("ping -c 5 -W 1 %s 2>&1", addr)
307 function diag_traceroute(addr)
308 diag_command("traceroute -q 1 -w 1 -n %s 2>&1", addr)
311 function diag_nslookup(addr)
312 diag_command("nslookup %s 2>&1", addr)
315 function diag_ping6(addr)
316 diag_command("ping6 -c 5 %s 2>&1", addr)
319 function diag_traceroute6(addr)
320 diag_command("traceroute6 -q 1 -w 2 -n %s 2>&1", addr)