62e888c9214166758e1ce2a56fb1c24930de4749
[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", "status", "mwan"},
14                 alias("admin", "status", "mwan", "overview"),
15                 _("Load Balancing"), 600)
16
17         entry({"admin", "status", "mwan", "overview"},
18                 template("mwan/status_interface"))
19         entry({"admin", "status", "mwan", "detail"},
20                 template("mwan/status_detail"))
21         entry({"admin", "status", "mwan", "diagnostics"},
22                 template("mwan/status_diagnostics"))
23         entry({"admin", "status", "mwan", "troubleshooting"},
24                 template("mwan/status_troubleshooting"))
25         entry({"admin", "status", "mwan", "interface_status"},
26                 call("mwan_Status"))
27         entry({"admin", "status", "mwan", "detailed_status"},
28                 call("detailedStatus"))
29         entry({"admin", "status", "mwan", "diagnostics_display"},
30                 call("diagnosticsData"), nil).leaf = true
31         entry({"admin", "status", "mwan", "troubleshooting_display"},
32                 call("troubleshootingData"))
33
34
35         entry({"admin", "network", "mwan"},
36                 alias("admin", "network", "mwan", "interface"),
37                 _("Load Balancing"), 600)
38
39         entry({"admin", "network", "mwan", "globals"},
40                 cbi("mwan/globalsconfig"),
41                 _("Globals"), 5).leaf = true
42         entry({"admin", "network", "mwan", "interface"},
43                 arcombine(cbi("mwan/interface"), cbi("mwan/interfaceconfig")),
44                 _("Interfaces"), 10).leaf = true
45         entry({"admin", "network", "mwan", "member"},
46                 arcombine(cbi("mwan/member"), cbi("mwan/memberconfig")),
47                 _("Members"), 20).leaf = true
48         entry({"admin", "network", "mwan", "policy"},
49                 arcombine(cbi("mwan/policy"), cbi("mwan/policyconfig")),
50                 _("Policies"), 30).leaf = true
51         entry({"admin", "network", "mwan", "rule"},
52                 arcombine(cbi("mwan/rule"), cbi("mwan/ruleconfig")),
53                 _("Rules"), 40).leaf = true
54         entry({"admin", "network", "mwan", "notify"},
55                 cbi("mwan/notify"),
56                 _("Notification"), 50).leaf = true
57 end
58
59 function mwan_Status()
60         local status = ut.ubus("mwan3", "status", {})
61
62         luci.http.prepare_content("application/json")
63         if status ~= nil then
64                 luci.http.write_json(status)
65         else
66                 luci.http.write_json({})
67         end
68 end
69
70 function detailedStatus()
71         local mArray = {}
72
73         -- detailed mwan status
74         local detailStatusInfo = ut.trim(sys.exec("/usr/sbin/mwan3 status"))
75         if detailStatusInfo ~= "" then
76                 mArray.mwandetail = { detailStatusInfo }
77         end
78
79         luci.http.prepare_content("application/json")
80         luci.http.write_json(mArray)
81 end
82
83 function diagnosticsData(interface, tool, task)
84         function getInterfaceNumber()
85                 local number = 0
86                 uci.cursor():foreach("mwan3", "interface",
87                         function (section)
88                                 number = number+1
89                                 if section[".name"] == interface then
90                                         interfaceNumber = number
91                                 end
92                         end
93                 )
94         end
95
96         local mArray = {}
97
98         local results = ""
99         if tool == "service" then
100                 os.execute("/usr/sbin/mwan3 " .. task)
101                 if task == "restart" then
102                         results = "MWAN3 restarted"
103                 elseif task == "stop" then
104                         results = "MWAN3 stopped"
105                 else
106                         results = "MWAN3 started"
107                 end
108         else
109                 local interfaceDevice = ut.trim(sys.exec("uci -q -p /var/state get network." .. interface .. ".ifname"))
110                 if interfaceDevice ~= "" then
111                         if tool == "ping" then
112                                 local gateway = ut.trim(sys.exec("route -n | awk '{if ($8 == \"" .. interfaceDevice .. "\" && $1 == \"0.0.0.0\" && $3 == \"0.0.0.0\") print $2}'"))
113                                 if gateway ~= "" then
114                                         if task == "gateway" then
115                                                 local pingCommand = "ping -c 3 -W 2 -I " .. interfaceDevice .. " " .. gateway
116                                                 results = pingCommand .. "\n\n" .. sys.exec(pingCommand)
117                                         else
118                                                 local tracked = ut.trim(sys.exec("uci -q -p /var/state get mwan3." .. interface .. ".track_ip"))
119                                                 if tracked ~= "" then
120                                                         for z in tracked:gmatch("[^ ]+") do
121                                                                 local pingCommand = "ping -c 3 -W 2 -I " .. interfaceDevice .. " " .. z
122                                                                 results = results .. pingCommand .. "\n\n" .. sys.exec(pingCommand) .. "\n\n"
123                                                         end
124                                                 else
125                                                         results = "No tracking IP addresses configured on " .. interface
126                                                 end
127                                         end
128                                 else
129                                         results = "No default gateway for " .. interface .. " found. Default route does not exist or is configured incorrectly"
130                                 end
131                         elseif tool == "rulechk" then
132                                 getInterfaceNumber()
133                                 local rule1 = sys.exec(ip .. "rule | grep $(echo $((" .. interfaceNumber .. " + 1000)))")
134                                 local rule2 = sys.exec(ip .. "rule | grep $(echo $((" .. interfaceNumber .. " + 2000)))")
135                                 if rule1 ~= "" and rule2 ~= "" then
136                                         results = "All required interface IP rules found:\n\n" .. rule1 .. rule2
137                                 elseif rule1 ~= "" or rule2 ~= "" then
138                                         results = "Missing 1 of the 2 required interface IP rules\n\n\nRules found:\n\n" .. rule1 .. rule2
139                                 else
140                                         results = "Missing both of the required interface IP rules"
141                                 end
142                         elseif tool == "routechk" then
143                                 getInterfaceNumber()
144                                 local routeTable = sys.exec(ip .. "route list table " .. interfaceNumber)
145                                 if routeTable ~= "" then
146                                         results = "Interface routing table " .. interfaceNumber .. " was found:\n\n" .. routeTable
147                                 else
148                                         results = "Missing required interface routing table " .. interfaceNumber
149                                 end
150                         elseif tool == "hotplug" then
151                                 if task == "ifup" then
152                                         os.execute("/usr/sbin/mwan3 ifup " .. interface)
153                                         results = "Hotplug ifup sent to interface " .. interface .. "..."
154                                 else
155                                         os.execute("/usr/sbin/mwan3 ifdown " .. interface)
156                                         results = "Hotplug ifdown sent to interface " .. interface .. "..."
157                                 end
158                         end
159                 else
160                         results = "Unable to perform diagnostic tests on " .. interface .. ". There is no physical or virtual device associated with this interface"
161                 end
162         end
163         if results ~= "" then
164                 results = ut.trim(results)
165                 mArray.diagnostics = { results }
166         end
167
168         luci.http.prepare_content("application/json")
169         luci.http.write_json(mArray)
170 end
171
172 function troubleshootingData()
173         local ver = require "luci.version"
174
175         local mArray = {}
176
177         -- software versions
178         local wrtRelease = ut.trim(ver.distversion)
179                 if wrtRelease ~= "" then
180                         wrtRelease = "OpenWrt - " .. wrtRelease
181                 else
182                         wrtRelease = "OpenWrt - unknown"
183                 end
184         local luciRelease = ut.trim(ver.luciversion)
185                 if luciRelease ~= "" then
186                         luciRelease = "\nLuCI - " .. luciRelease
187                 else
188                         luciRelease = "\nLuCI - unknown"
189                 end
190         local mwanVersion = ut.trim(sys.exec("opkg info mwan3 | grep Version | awk '{print $2}'"))
191                 if mwanVersion ~= "" then
192                         mwanVersion = "\n\nmwan3 - " .. mwanVersion
193                 else
194                         mwanVersion = "\n\nmwan3 - unknown"
195                 end
196         local mwanLuciVersion = ut.trim(sys.exec("opkg info luci-app-mwan3 | grep Version | awk '{print $2}'"))
197                 if mwanLuciVersion ~= "" then
198                         mwanLuciVersion = "\nmwan3-luci - " .. mwanLuciVersion
199                 else
200                         mwanLuciVersion = "\nmwan3-luci - unknown"
201                 end
202         mArray.versions = { wrtRelease .. luciRelease .. mwanVersion .. mwanLuciVersion }
203
204         -- mwan config
205         local mwanConfig = ut.trim(sys.exec("cat /etc/config/mwan3"))
206                 if mwanConfig == "" then
207                         mwanConfig = "No data found"
208                 end
209         mArray.mwanconfig = { mwanConfig }
210
211         -- network config
212         local networkConfig = ut.trim(sys.exec("cat /etc/config/network | sed -e 's/.*username.*/       USERNAME HIDDEN/' -e 's/.*password.*/   PASSWORD HIDDEN/'"))
213                 if networkConfig == "" then
214                         networkConfig = "No data found"
215                 end
216         mArray.netconfig = { networkConfig }
217
218         -- wireless config
219         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/'"))
220                 if wirelessConfig == "" then
221                         wirelessConfig = "No data found"
222                 end
223         mArray.wificonfig = { wirelessConfig }
224         
225         -- ifconfig
226         local ifconfig = ut.trim(sys.exec("ifconfig"))
227                 if ifconfig == "" then
228                         ifconfig = "No data found"
229                 end
230         mArray.ifconfig = { ifconfig }
231
232         -- route -n
233         local routeShow = ut.trim(sys.exec("route -n"))
234                 if routeShow == "" then
235                         routeShow = "No data found"
236                 end
237         mArray.routeshow = { routeShow }
238
239         -- ip rule show
240         local ipRuleShow = ut.trim(sys.exec(ip .. "rule show"))
241                 if ipRuleShow == "" then
242                         ipRuleShow = "No data found"
243                 end
244         mArray.iprule = { ipRuleShow }
245
246         -- ip route list table 1-250
247         local routeList, routeString = ut.trim(sys.exec(ip .. "rule | sed 's/://g' 2>/dev/null | awk '$1>=2001 && $1<=2250' | awk '{print $NF}'")), ""
248                 if routeList ~= "" then
249                         for line in routeList:gmatch("[^\r\n]+") do
250                                 routeString = routeString .. line .. "\n" .. sys.exec(ip .. "route list table " .. line)
251                         end
252                         routeString = ut.trim(routeString)
253                 else
254                         routeString = "No data found"
255                 end
256         mArray.routelist = { routeString }
257
258         -- default firewall output policy
259         local firewallOut = ut.trim(sys.exec("uci -q -p /var/state get firewall.@defaults[0].output"))
260                 if firewallOut == "" then
261                         firewallOut = "No data found"
262                 end
263         mArray.firewallout = { firewallOut }
264
265         -- iptables
266         local iptables = ut.trim(sys.exec("iptables -L -t mangle -v -n"))
267                 if iptables == "" then
268                         iptables = "No data found"
269                 end
270         mArray.iptables = { iptables }
271
272         luci.http.prepare_content("application/json")
273         luci.http.write_json(mArray)
274 end