luci-app-mwan3: Fix "ip" command path
[project/luci.git] / applications / luci-app-mwan3 / luasrc / controller / mwan3.lua
1 module("luci.controller.mwan3", package.seeall)
2
3 sys = require "luci.sys"
4 ut = require "luci.util"
5
6 ip = "ip -4 "
7
8 function index()
9 if not nixio.fs.access("/etc/config/mwan3") then
10 return
11 end
12
13 entry({"admin", "network", "mwan"},
14 alias("admin", "network", "mwan", "overview"),
15 _("Load Balancing"), 600)
16
17 entry({"admin", "network", "mwan", "overview"},
18 alias("admin", "network", "mwan", "overview", "overview_interface"),
19 _("Overview"), 10)
20 entry({"admin", "network", "mwan", "overview", "overview_interface"},
21 template("mwan/overview_interface"))
22 entry({"admin", "network", "mwan", "overview", "interface_status"},
23 call("interfaceStatus"))
24 entry({"admin", "network", "mwan", "overview", "overview_detailed"},
25 template("mwan/overview_detailed"))
26 entry({"admin", "network", "mwan", "overview", "detailed_status"},
27 call("detailedStatus"))
28
29 entry({"admin", "network", "mwan", "configuration"},
30 alias("admin", "network", "mwan", "configuration", "interface"),
31 _("Configuration"), 20)
32 entry({"admin", "network", "mwan", "configuration", "interface"},
33 arcombine(cbi("mwan/interface"), cbi("mwan/interfaceconfig")),
34 _("Interfaces"), 10).leaf = true
35 entry({"admin", "network", "mwan", "configuration", "member"},
36 arcombine(cbi("mwan/member"), cbi("mwan/memberconfig")),
37 _("Members"), 20).leaf = true
38 entry({"admin", "network", "mwan", "configuration", "policy"},
39 arcombine(cbi("mwan/policy"), cbi("mwan/policyconfig")),
40 _("Policies"), 30).leaf = true
41 entry({"admin", "network", "mwan", "configuration", "rule"},
42 arcombine(cbi("mwan/rule"), cbi("mwan/ruleconfig")),
43 _("Rules"), 40).leaf = true
44
45 entry({"admin", "network", "mwan", "advanced"},
46 alias("admin", "network", "mwan", "advanced", "hotplugscript"),
47 _("Advanced"), 100)
48 entry({"admin", "network", "mwan", "advanced", "hotplugscript"},
49 form("mwan/advanced_hotplugscript"))
50 entry({"admin", "network", "mwan", "advanced", "mwanconfig"},
51 form("mwan/advanced_mwanconfig"))
52 entry({"admin", "network", "mwan", "advanced", "networkconfig"},
53 form("mwan/advanced_networkconfig"))
54 entry({"admin", "network", "mwan", "advanced", "wirelessconfig"},
55 form("mwan/advanced_wirelessconfig"))
56 entry({"admin", "network", "mwan", "advanced", "diagnostics"},
57 template("mwan/advanced_diagnostics"))
58 entry({"admin", "network", "mwan", "advanced", "diagnostics_display"},
59 call("diagnosticsData"), nil).leaf = true
60 entry({"admin", "network", "mwan", "advanced", "troubleshooting"},
61 template("mwan/advanced_troubleshooting"))
62 entry({"admin", "network", "mwan", "advanced", "troubleshooting_display"},
63 call("troubleshootingData"))
64 end
65
66 function getInterfaceStatus(ruleNumber, interfaceName)
67 if ut.trim(sys.exec("uci -q -p /var/state get mwan3." .. interfaceName .. ".enabled")) == "1" then
68 if ut.trim(sys.exec(ip .. "route list table " .. ruleNumber)) ~= "" then
69 if ut.trim(sys.exec("uci -q -p /var/state get mwan3." .. interfaceName .. ".track_ip")) ~= "" then
70 return "online"
71 else
72 return "notMonitored"
73 end
74 else
75 return "offline"
76 end
77 else
78 return "notEnabled"
79 end
80 end
81
82 function getInterfaceName()
83 local ruleNumber, status = 0, ""
84 uci.cursor():foreach("mwan3", "interface",
85 function (section)
86 ruleNumber = ruleNumber+1
87 status = status .. section[".name"] .. "[" .. getInterfaceStatus(ruleNumber, section[".name"]) .. "]"
88 end
89 )
90 return status
91 end
92
93 function interfaceStatus()
94 local ntm = require "luci.model.network".init()
95
96 local mArray = {}
97
98 -- overview status
99 local statusString = getInterfaceName()
100 if statusString ~= "" then
101 mArray.wans = {}
102 wansid = {}
103
104 for wanName, interfaceState in string.gfind(statusString, "([^%[]+)%[([^%]]+)%]") do
105 local wanInterfaceName = ut.trim(sys.exec("uci -q -p /var/state get network." .. wanName .. ".ifname"))
106 if wanInterfaceName == "" then
107 wanInterfaceName = "X"
108 end
109 local wanDeviceLink = ntm:get_interface(wanInterfaceName)
110 wanDeviceLink = wanDeviceLink and wanDeviceLink:get_network()
111 wanDeviceLink = wanDeviceLink and wanDeviceLink:adminlink() or "#"
112 wansid[wanName] = #mArray.wans + 1
113 mArray.wans[wansid[wanName]] = { name = wanName, link = wanDeviceLink, ifname = wanInterfaceName, status = interfaceState }
114 end
115 end
116
117 -- overview status log
118 local mwanLog = ut.trim(sys.exec("logread | grep mwan3 | tail -n 50 | sed 'x;1!H;$!d;x' 2>/dev/null"))
119 if mwanLog ~= "" then
120 mArray.mwanlog = { mwanLog }
121 end
122
123 luci.http.prepare_content("application/json")
124 luci.http.write_json(mArray)
125 end
126
127 function detailedStatus()
128 local mArray = {}
129
130 -- detailed mwan status
131 local detailStatusInfo = ut.trim(sys.exec("/usr/sbin/mwan3 status"))
132 if detailStatusInfo ~= "" then
133 mArray.mwandetail = { detailStatusInfo }
134 end
135
136 luci.http.prepare_content("application/json")
137 luci.http.write_json(mArray)
138 end
139
140 function diagnosticsData(interface, tool, task)
141 function getInterfaceNumber()
142 local number = 0
143 uci.cursor():foreach("mwan3", "interface",
144 function (section)
145 number = number+1
146 if section[".name"] == interface then
147 interfaceNumber = number
148 end
149 end
150 )
151 end
152
153 local mArray = {}
154
155 local results = ""
156 if tool == "service" then
157 os.execute("/usr/sbin/mwan3 " .. task)
158 if task == "restart" then
159 results = "MWAN3 restarted"
160 elseif task == "stop" then
161 results = "MWAN3 stopped"
162 else
163 results = "MWAN3 started"
164 end
165 else
166 local interfaceDevice = ut.trim(sys.exec("uci -q -p /var/state get network." .. interface .. ".ifname"))
167 if interfaceDevice ~= "" then
168 if tool == "ping" then
169 local gateway = ut.trim(sys.exec("route -n | awk '{if ($8 == \"" .. interfaceDevice .. "\" && $1 == \"0.0.0.0\" && $3 == \"0.0.0.0\") print $2}'"))
170 if gateway ~= "" then
171 if task == "gateway" then
172 local pingCommand = "ping -c 3 -W 2 -I " .. interfaceDevice .. " " .. gateway
173 results = pingCommand .. "\n\n" .. sys.exec(pingCommand)
174 else
175 local tracked = ut.trim(sys.exec("uci -q -p /var/state get mwan3." .. interface .. ".track_ip"))
176 if tracked ~= "" then
177 for z in tracked:gmatch("[^ ]+") do
178 local pingCommand = "ping -c 3 -W 2 -I " .. interfaceDevice .. " " .. z
179 results = results .. pingCommand .. "\n\n" .. sys.exec(pingCommand) .. "\n\n"
180 end
181 else
182 results = "No tracking IP addresses configured on " .. interface
183 end
184 end
185 else
186 results = "No default gateway for " .. interface .. " found. Default route does not exist or is configured incorrectly"
187 end
188 elseif tool == "rulechk" then
189 getInterfaceNumber()
190 local rule1 = sys.exec(ip .. "rule | grep $(echo $((" .. interfaceNumber .. " + 1000)))")
191 local rule2 = sys.exec(ip .. "rule | grep $(echo $((" .. interfaceNumber .. " + 2000)))")
192 if rule1 ~= "" and rule2 ~= "" then
193 results = "All required interface IP rules found:\n\n" .. rule1 .. rule2
194 elseif rule1 ~= "" or rule2 ~= "" then
195 results = "Missing 1 of the 2 required interface IP rules\n\n\nRules found:\n\n" .. rule1 .. rule2
196 else
197 results = "Missing both of the required interface IP rules"
198 end
199 elseif tool == "routechk" then
200 getInterfaceNumber()
201 local routeTable = sys.exec(ip .. "route list table " .. interfaceNumber)
202 if routeTable ~= "" then
203 results = "Interface routing table " .. interfaceNumber .. " was found:\n\n" .. routeTable
204 else
205 results = "Missing required interface routing table " .. interfaceNumber
206 end
207 elseif tool == "hotplug" then
208 if task == "ifup" then
209 os.execute("/usr/sbin/mwan3 ifup " .. interface)
210 results = "Hotplug ifup sent to interface " .. interface .. "..."
211 else
212 os.execute("/usr/sbin/mwan3 ifdown " .. interface)
213 results = "Hotplug ifdown sent to interface " .. interface .. "..."
214 end
215 end
216 else
217 results = "Unable to perform diagnostic tests on " .. interface .. ". There is no physical or virtual device associated with this interface"
218 end
219 end
220 if results ~= "" then
221 results = ut.trim(results)
222 mArray.diagnostics = { results }
223 end
224
225 luci.http.prepare_content("application/json")
226 luci.http.write_json(mArray)
227 end
228
229 function troubleshootingData()
230 local ver = require "luci.version"
231
232 local mArray = {}
233
234 -- software versions
235 local wrtRelease = ut.trim(ver.distversion)
236 if wrtRelease ~= "" then
237 wrtRelease = "OpenWrt - " .. wrtRelease
238 else
239 wrtRelease = "OpenWrt - unknown"
240 end
241 local luciRelease = ut.trim(ver.luciversion)
242 if luciRelease ~= "" then
243 luciRelease = "\nLuCI - " .. luciRelease
244 else
245 luciRelease = "\nLuCI - unknown"
246 end
247 local mwanVersion = ut.trim(sys.exec("opkg info mwan3 | grep Version | awk '{print $2}'"))
248 if mwanVersion ~= "" then
249 mwanVersion = "\n\nmwan3 - " .. mwanVersion
250 else
251 mwanVersion = "\n\nmwan3 - unknown"
252 end
253 local mwanLuciVersion = ut.trim(sys.exec("opkg info luci-app-mwan3 | grep Version | awk '{print $2}'"))
254 if mwanLuciVersion ~= "" then
255 mwanLuciVersion = "\nmwan3-luci - " .. mwanLuciVersion
256 else
257 mwanLuciVersion = "\nmwan3-luci - unknown"
258 end
259 mArray.versions = { wrtRelease .. luciRelease .. mwanVersion .. mwanLuciVersion }
260
261 -- mwan config
262 local mwanConfig = ut.trim(sys.exec("cat /etc/config/mwan3"))
263 if mwanConfig == "" then
264 mwanConfig = "No data found"
265 end
266 mArray.mwanconfig = { mwanConfig }
267
268 -- network config
269 local networkConfig = ut.trim(sys.exec("cat /etc/config/network | sed -e 's/.*username.*/ USERNAME HIDDEN/' -e 's/.*password.*/ PASSWORD HIDDEN/'"))
270 if networkConfig == "" then
271 networkConfig = "No data found"
272 end
273 mArray.netconfig = { networkConfig }
274
275 -- wireless config
276 local wirelessConfig = ut.trim(sys.exec("cat /etc/config/wireless | sed -e 's/.*username.*/ USERNAME HIDDEN/' -e 's/.*password.*/ PASSWORD HIDDEN/' -e 's/.*key.*/ KEY HIDDEN/'"))
277 if wirelessConfig == "" then
278 wirelessConfig = "No data found"
279 end
280 mArray.wificonfig = { wirelessConfig }
281
282 -- ifconfig
283 local ifconfig = ut.trim(sys.exec("ifconfig"))
284 if ifconfig == "" then
285 ifconfig = "No data found"
286 end
287 mArray.ifconfig = { ifconfig }
288
289 -- route -n
290 local routeShow = ut.trim(sys.exec("route -n"))
291 if routeShow == "" then
292 routeShow = "No data found"
293 end
294 mArray.routeshow = { routeShow }
295
296 -- ip rule show
297 local ipRuleShow = ut.trim(sys.exec(ip .. "rule show"))
298 if ipRuleShow == "" then
299 ipRuleShow = "No data found"
300 end
301 mArray.iprule = { ipRuleShow }
302
303 -- ip route list table 1-250
304 local routeList, routeString = ut.trim(sys.exec(ip .. "rule | sed 's/://g' 2>/dev/null | awk '$1>=2001 && $1<=2250' | awk '{print $NF}'")), ""
305 if routeList ~= "" then
306 for line in routeList:gmatch("[^\r\n]+") do
307 routeString = routeString .. line .. "\n" .. sys.exec(ip .. "route list table " .. line)
308 end
309 routeString = ut.trim(routeString)
310 else
311 routeString = "No data found"
312 end
313 mArray.routelist = { routeString }
314
315 -- default firewall output policy
316 local firewallOut = ut.trim(sys.exec("uci -q -p /var/state get firewall.@defaults[0].output"))
317 if firewallOut == "" then
318 firewallOut = "No data found"
319 end
320 mArray.firewallout = { firewallOut }
321
322 -- iptables
323 local iptables = ut.trim(sys.exec("iptables -L -t mangle -v -n"))
324 if iptables == "" then
325 iptables = "No data found"
326 end
327 mArray.iptables = { iptables }
328
329 luci.http.prepare_content("application/json")
330 luci.http.write_json(mArray)
331 end