1 module("luci.controller.olsr", package.seeall)
3 local neigh_table = nil
4 local ifaddr_table = nil
8 if nixio.fs.access("/etc/config/olsrd") then
11 if nixio.fs.access("/etc/config/olsrd6") then
14 if not ipv4 and not ipv6 then
18 require("luci.model.uci")
19 local uci = luci.model.uci.cursor_state()
21 uci:foreach("olsrd", "olsrd", function(s)
22 if s.SmartGateway and s.SmartGateway == "yes" then has_smartgw = true end
25 local page = node("admin", "status", "olsr")
26 page.target = template("status-olsr/overview")
27 page.title = _("OLSR")
30 local page = node("admin", "status", "olsr", "json")
31 page.target = call("action_json")
35 local page = node("admin", "status", "olsr", "neighbors")
36 page.target = call("action_neigh")
37 page.title = _("Neighbours")
41 local page = node("admin", "status", "olsr", "routes")
42 page.target = call("action_routes")
43 page.title = _("Routes")
46 local page = node("admin", "status", "olsr", "topology")
47 page.target = call("action_topology")
48 page.title = _("Topology")
51 local page = node("admin", "status", "olsr", "hna")
52 page.target = call("action_hna")
56 local page = node("admin", "status", "olsr", "mid")
57 page.target = call("action_mid")
62 local page = node("admin", "status", "olsr", "smartgw")
63 page.target = call("action_smartgw")
64 page.title = _("SmartGW")
68 local page = node("admin", "status", "olsr", "interfaces")
69 page.target = call("action_interfaces")
70 page.title = _("Interfaces")
74 {"admin", "services", "olsrd", "display"},
75 cbi("olsr/olsrddisplay"), _("Display")
80 function action_json()
81 local http = require "luci.http"
82 local utl = require "luci.util"
83 local uci = require "luci.model.uci".cursor()
87 local v4_port = tonumber(uci:get("olsrd", "olsrd_jsoninfo", "port") or "") or 9090
88 local v6_port = tonumber(uci:get("olsrd6", "olsrd_jsoninfo", "port") or "") or 9090
90 jsonreq4 = utl.exec("(echo /status | nc 127.0.0.1 %d | sed -n '/^[}{ ]/p') 2>/dev/null" % v4_port)
91 jsonreq6 = utl.exec("(echo /status | nc ::1 %d | sed -n '/^[}{ ]/p') 2>/dev/null" % v6_port)
92 http.prepare_content("application/json")
93 if not jsonreq4 or jsonreq4 == "" then
96 if not jsonreq6 or jsonreq6 == "" then
99 http.write('{"v4":' .. jsonreq4 .. ', "v6":' .. jsonreq6 .. '}')
103 local function local_mac_lookup(ipaddr)
105 for _, rt in ipairs(luci.ip.routes({ type = 1, src = ipaddr })) do
106 local link = rt.dev and luci.ip.link(rt.dev)
107 local mac = link and luci.ip.checkmac(link.mac)
108 if mac then return mac end
112 local function remote_mac_lookup(ipaddr)
114 for _, n in ipairs(luci.ip.neighbors({ dest = ipaddr })) do
115 local mac = luci.ip.checkmac(n.mac)
116 if mac then return mac end
120 function action_neigh(json)
121 local data, has_v4, has_v6, error = fetch_jsoninfo('links')
127 local uci = require "luci.model.uci".cursor_state()
128 local resolve = uci:get("luci_olsr", "general", "resolve")
129 local ntm = require "luci.model.network".init()
130 local devices = ntm:get_wifidevs()
131 local sys = require "luci.sys"
133 --local neightbl = require "neightbl"
134 local ntm = require "luci.model.network"
135 local ipc = require "luci.ip"
136 local nxo = require "nixio"
139 ipc.routes({ family = 4, type = 1, dest_exact = "0.0.0.0/0" },
140 function(rt) defaultgw = rt.gw end)
142 local function compare(a,b)
143 if a.proto == b.proto then
144 return a.linkCost < b.linkCost
146 return a.proto < b.proto
150 for _, dev in ipairs(devices) do
151 for _, net in ipairs(dev:get_wifinets()) do
152 local radio = net:get_device()
153 assoclist[#assoclist+1] = {}
154 assoclist[#assoclist]['ifname'] = net:ifname()
155 assoclist[#assoclist]['network'] = net:network()[1]
156 assoclist[#assoclist]['device'] = radio and radio:name() or nil
157 assoclist[#assoclist]['list'] = net:assoclist()
161 for k, v in ipairs(data) do
169 if resolve == "1" then
170 hostname = nixio.getnameinfo(v.remoteIP, nil, 100)
172 v.hostname = hostname
176 local interface = ntm:get_status_by_address(v.localIP)
177 local lmac = local_mac_lookup(v.localIP)
178 local rmac = remote_mac_lookup(v.remoteIP)
180 for _, val in ipairs(assoclist) do
181 if val.network == interface and val.list then
182 local assocmac, assot
183 for assocmac, assot in pairs(val.list) do
184 if rmac == luci.ip.checkmac(assocmac) then
185 signal = tonumber(assot.signal)
186 noise = tonumber(assot.noise)
187 snr = (noise*-1) - (signal*-1)
193 v.interface = interface
205 if defaultgw == v.remoteIP then
210 table.sort(data, compare)
211 luci.template.render("status-olsr/neighbors", {links=data, has_v4=has_v4, has_v6=has_v6})
214 function action_routes()
215 local data, has_v4, has_v6, error = fetch_jsoninfo('routes')
220 local uci = require "luci.model.uci".cursor_state()
221 local resolve = uci:get("luci_olsr", "general", "resolve")
223 for k, v in ipairs(data) do
224 if resolve == "1" then
225 local hostname = nixio.getnameinfo(v.gateway, nil, 100)
227 v.hostname = hostname
232 local function compare(a,b)
233 if a.proto == b.proto then
234 return a.rtpMetricCost < b.rtpMetricCost
236 return a.proto < b.proto
240 table.sort(data, compare)
241 luci.template.render("status-olsr/routes", {routes=data, has_v4=has_v4, has_v6=has_v6})
244 function action_topology()
245 local data, has_v4, has_v6, error = fetch_jsoninfo('topology')
250 local function compare(a,b)
251 if a.proto == b.proto then
252 return a.tcEdgeCost < b.tcEdgeCost
254 return a.proto < b.proto
258 table.sort(data, compare)
259 luci.template.render("status-olsr/topology", {routes=data, has_v4=has_v4, has_v6=has_v6})
262 function action_hna()
263 local data, has_v4, has_v6, error = fetch_jsoninfo('hna')
268 local uci = require "luci.model.uci".cursor_state()
269 local resolve = uci:get("luci_olsr", "general", "resolve")
271 local function compare(a,b)
272 if a.proto == b.proto then
273 return a.genmask < b.genmask
275 return a.proto < b.proto
279 for k, v in ipairs(data) do
280 if resolve == "1" then
281 hostname = nixio.getnameinfo(v.gateway, nil, 100)
283 v.hostname = hostname
286 if v.validityTime then
287 v.validityTime = tonumber(string.format("%.0f", v.validityTime / 1000))
291 table.sort(data, compare)
292 luci.template.render("status-olsr/hna", {hna=data, has_v4=has_v4, has_v6=has_v6})
295 function action_mid()
296 local data, has_v4, has_v6, error = fetch_jsoninfo('mid')
301 local function compare(a,b)
302 if a.proto == b.proto then
303 return a.ipAddress < b.ipAddress
305 return a.proto < b.proto
309 table.sort(data, compare)
310 luci.template.render("status-olsr/mid", {mids=data, has_v4=has_v4, has_v6=has_v6})
313 function action_smartgw()
314 local data, has_v4, has_v6, error = fetch_jsoninfo('gateways')
319 local function compare(a,b)
320 if a.proto == b.proto then
321 return a.tcPathCost < b.tcPathCost
323 return a.proto < b.proto
327 table.sort(data, compare)
328 luci.template.render("status-olsr/smartgw", {gws=data, has_v4=has_v4, has_v6=has_v6})
331 function action_interfaces()
332 local data, has_v4, has_v6, error = fetch_jsoninfo('interfaces')
337 local function compare(a,b)
338 return a.proto < b.proto
341 table.sort(data, compare)
342 luci.template.render("status-olsr/interfaces", {iface=data, has_v4=has_v4, has_v6=has_v6})
346 function fetch_jsoninfo(otable)
347 local uci = require "luci.model.uci".cursor_state()
348 local utl = require "luci.util"
349 local json = require "luci.json"
350 local IpVersion = uci:get_first("olsrd", "olsrd","IpVersion")
353 local v4_port = tonumber(uci:get("olsrd", "olsrd_jsoninfo", "port") or "") or 9090
354 local v6_port = tonumber(uci:get("olsrd6", "olsrd_jsoninfo", "port") or "") or 9090
356 jsonreq4 = utl.exec("(echo /%s | nc 127.0.0.1 %d | sed -n '/^[}{ ]/p') 2>/dev/null" %{ otable, v4_port })
357 jsonreq6 = utl.exec("(echo /%s | nc ::1 %d | sed -n '/^[}{ ]/p') 2>/dev/null" %{ otable, v6_port })
365 if jsonreq4 == '' and jsonreq6 == '' then
366 luci.template.render("status-olsr/error_olsr")
367 return nil, 0, 0, true
370 if jsonreq4 ~= "" then
372 jsondata4 = json.decode(jsonreq4)
373 if otable == 'status' then
374 data4 = jsondata4 or {}
376 data4 = jsondata4[otable] or {}
379 for k, v in ipairs(data4) do
380 data4[k]['proto'] = '4'
384 if jsonreq6 ~= "" then
386 jsondata6 = json.decode(jsonreq6)
387 if otable == 'status' then
388 data6 = jsondata6 or {}
390 data6 = jsondata6[otable] or {}
392 for k, v in ipairs(data6) do
393 data6[k]['proto'] = '6'
397 for k, v in ipairs(data6) do
398 table.insert(data4, v)
401 return data4, has_v4, has_v6, false