applications/luci-olsr: Add Hostnames, show v6 infos. Most parts of this are from...
[project/luci.git] / applications / luci-olsr / luasrc / controller / olsr.lua
1 module("luci.controller.olsr", package.seeall)
2
3 function index()
4 if not nixio.fs.access("/etc/config/olsrd") then
5 return
6 end
7
8 require("luci.i18n").loadc("olsr")
9 local i18n = luci.i18n.translate
10
11 local page = node("admin", "status", "olsr")
12 page.target = call("action_index")
13 page.title = "OLSR"
14 page.i18n = "olsr"
15 page.subindex = true
16
17 local page = node("admin", "status", "olsr", "routes")
18 page.target = call("action_routes")
19 page.title = i18n("Routen")
20 page.order = 10
21
22 local page = node("admin", "status", "olsr", "topology")
23 page.target = call("action_topology")
24 page.title = i18n("Topologie")
25 page.order = 20
26
27 local page = node("admin", "status", "olsr", "hna")
28 page.target = call("action_hna")
29 page.title = "HNA"
30 page.order = 30
31
32 local page = node("admin", "status", "olsr", "mid")
33 page.target = call("action_mid")
34 page.title = "MID"
35 page.order = 50
36
37 local ol = entry(
38 {"admin", "services", "olsrd"},
39 cbi("olsr/olsrd"), "OLSR"
40 )
41 ol.i18n = "olsr"
42 ol.subindex = true
43
44 entry(
45 {"admin", "services", "olsrd", "iface"},
46 cbi("olsr/olsrdiface")
47 ).leaf = true
48
49 entry(
50 {"admin", "services", "olsrd", "hna"},
51 cbi("olsr/olsrdhna"), "HNA Announcements"
52 )
53
54 oplg = entry(
55 {"admin", "services", "olsrd", "plugins"},
56 cbi("olsr/olsrdplugins"), "Plugins"
57 )
58 oplg.i18n = "olsr"
59 oplg.leaf = true
60 oplg.subindex = true
61
62 local uci = require("luci.model.uci").cursor()
63 uci:foreach("olsrd", "LoadPlugin",
64 function (section)
65 local lib = section.library
66 entry(
67 {"admin", "services", "olsrd", "plugins", lib },
68 cbi("olsr/olsrdplugins"),
69 nil --'Plugin "%s"' % lib:gsub("^olsrd_",""):gsub("%.so.+$","")
70 )
71 end
72 )
73 end
74
75 function action_index()
76 local data = fetch_txtinfo("links")
77
78 if not data or not data.Links then
79 luci.template.render("status-olsr/error_olsr")
80 return nil
81 end
82
83 local function compare(a, b)
84 local c = tonumber(a.Cost)
85 local d = tonumber(b.Cost)
86
87 if not c or c == 0 then
88 return false
89 end
90
91 if not d or d == 0 then
92 return true
93 end
94
95 return c < d
96 end
97
98 table.sort(data.Links, compare)
99
100 luci.template.render("status-olsr/index", {links=data.Links})
101 end
102
103 function action_routes()
104 local data = fetch_txtinfo("routes")
105
106 if not data or not data.Routes then
107 luci.template.render("status-olsr/error_olsr")
108 return nil
109 end
110
111 local function compare(a, b)
112 local c = tonumber(a.ETX)
113 local d = tonumber(b.ETX)
114
115 if not c or c == 0 then
116 return false
117 end
118
119 if not d or d == 0 then
120 return true
121 end
122
123 return c < d
124 end
125
126 table.sort(data.Routes, compare)
127
128 luci.template.render("status-olsr/routes", {routes=data.Routes})
129 end
130
131 function action_topology()
132 local data = fetch_txtinfo("topology")
133
134 if not data or not data.Topology then
135 luci.template.render("status-olsr/error_olsr")
136 return nil
137 end
138
139 local function compare(a, b)
140 return a["Dest. IP"] < b["Dest. IP"]
141 end
142
143 table.sort(data.Topology, compare)
144
145 luci.template.render("status-olsr/topology", {routes=data.Topology})
146 end
147
148 function action_hna()
149 local data = fetch_txtinfo("hna")
150
151 if not data or not data.HNA then
152 luci.template.render("status-olsr/error_olsr")
153 return nil
154 end
155
156 local function compare(a, b)
157 return a.Destination < b.Destination
158 end
159
160 table.sort(data.HNA, compare)
161
162 luci.template.render("status-olsr/hna", {routes=data.HNA})
163 end
164
165 function action_mid()
166 local data = fetch_txtinfo("mid")
167
168 if not data or not data.MID then
169 luci.template.render("status-olsr/error_olsr")
170 return nil
171 end
172
173 local function compare(a, b)
174 return a["IP address"] < b["IP address"]
175 end
176
177 table.sort(data.MID, compare)
178
179 luci.template.render("status-olsr/mid", {mids=data.MID})
180 end
181
182 function action_smartgw()
183 local data = fetch_txtinfo("gateways")
184
185 if not data or not data.Gateways then
186 luci.template.render("status-olsr/error_olsr")
187 return nil
188 end
189
190 local function compare(a, b)
191 return a["ETX"] < b["ETX"]
192 end
193
194 table.sort(data.Gateways, compare)
195
196 luci.template.render("status-olsr/smartgw", {gws=data.Gateways})
197 end
198
199
200
201 -- Internal
202 function fetch_txtinfo(otable)
203 require("luci.sys")
204 local uci = require "luci.model.uci".cursor_state()
205 otable = otable or ""
206 local rawdata = luci.sys.httpget("http://127.0.0.1:2006/"..otable)
207 local rawdatav6 = luci.sys.httpget("http://[::1]:2006/"..otable)
208 local data = {}
209 local dataindex = 0
210 local name = ""
211
212 if #rawdata ~= 0 then
213 local tables = luci.util.split(luci.util.trim(rawdata), "\r?\n\r?\n", nil, true)
214
215 for i, tbl in ipairs(tables) do
216 local lines = luci.util.split(tbl, "\r?\n", nil, true)
217 name = table.remove(lines, 1):sub(8)
218 local keys = luci.util.split(table.remove(lines, 1), "\t")
219 local split = #keys - 1
220 if not data[name] then
221 data[name] = {}
222 end
223
224 for j, line in ipairs(lines) do
225 dataindex = ( dataindex + 1 )
226 di = dataindex
227 local fields = luci.util.split(line, "\t", split)
228 data[name][di] = {}
229 for k, key in pairs(keys) do
230 if key == "Remote IP" or key == "Dest. IP" or key == "Gateway IP" or key == "Gateway" then
231 hostname = nixio.getnameinfo(fields[k], "inet")
232 if hostname then
233 data[name][di][key] = fields[k]
234 data[name][di]["Hostname"] = hostname
235 else
236 data[name][di][key] = fields[k]
237 end
238 elseif key == "Local IP" then
239 data[name][di][key] = fields[k]
240 data[name][di]['Local Device'] = fields[k]
241 uci:foreach("network", "interface",
242 function(s)
243 localip = string.gsub(fields[k], ' ', '')
244 if s.ipaddr == localip then
245 data[name][di]['Local Device'] = s['.name'] or interface
246 end
247 end)
248 elseif key == "Interface" then
249 data[name][di][key] = fields[k]
250 uci:foreach("network", "interface",
251 function(s)
252 interface = string.gsub(fields[k], ' ', '')
253 if s.ifname == interface then
254 data[name][di][key] = s['.name'] or interface
255 end
256 end)
257 else
258 data[name][di][key] = fields[k]
259 end
260 end
261 if data[name][di].Linkcost then
262 data[name][di].LinkQuality,
263 data[name][di].NLQ,
264 data[name][di].ETX =
265 data[name][di].Linkcost:match("([%w.]+)/([%w.]+)[%s]+([%w.]+)")
266 end
267 end
268 end
269 end
270
271 if #rawdatav6 ~= 0 then
272 local tables = luci.util.split(luci.util.trim(rawdatav6), "\r?\n\r?\n", nil, true)
273 for i, tbl in ipairs(tables) do
274 local lines = luci.util.split(tbl, "\r?\n", nil, true)
275 name = table.remove(lines, 1):sub(8)
276 local keys = luci.util.split(table.remove(lines, 1), "\t")
277 local split = #keys - 1
278 if not data[name] then
279 data[name] = {}
280 end
281 for j, line in ipairs(lines) do
282 dataindex = ( dataindex + 1 )
283 di = dataindex
284 local fields = luci.util.split(line, "\t", split)
285 data[name][di] = {}
286 for k, key in pairs(keys) do
287 if key == "Remote IP" then
288 hostname = nixio.getnameinfo(fields[k], "inet6")
289 if hostname then
290 data[name][di][key] = "[" .. fields[k] .. "]"
291 data[name][di]["Hostname"] = hostname
292 else
293 data[name][di][key] = "[" .. fields[k] .. "]"
294 end
295 elseif key == "Local IP" then
296 data[name][di][key] = fields[k]
297 data[name][di]['Local Device'] = fields[k]
298 uci:foreach("network", "interface",
299 function(s)
300 local localip = string.gsub(fields[k], ' ', '')
301 if s.ip6addr then
302 local ip6addr = string.gsub(s.ip6addr, '\/.*', '')
303 if ip6addr == localip then
304 data[name][di]['Local Device'] = s['.name'] or s.interface
305 end
306 end
307 end)
308 elseif key == "Dest. IP" then
309 data[name][di][key] = "[" .. fields[k] .. "]"
310 elseif key == "Last hop IP" then
311 data[name][di][key] = "[" .. fields[k] .. "]"
312 elseif key == "IP address" then
313 data[name][di][key] = "[" .. fields[k] .. "]"
314 elseif key == "Gateway" then
315 data[name][di][key] = "[" .. fields[k] .. "]"
316 else
317 data[name][di][key] = fields[k]
318 end
319 end
320
321 if data[name][di].Linkcost then
322 data[name][di].LinkQuality,
323 data[name][di].NLQ,
324 data[name][di].ETX =
325 data[name][di].Linkcost:match("([%w.]+)/([%w.]+)[%s]+([%w.]+)")
326 end
327 end
328 end
329 end
330
331
332 if data then
333 return data
334 end
335 end