network.lua 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705
  1. -- Copyright 2009-2015 Jo-Philipp Wich <jow@openwrt.org>
  2. -- Licensed to the public under the Apache License 2.0.
  3. local type, next, pairs, ipairs, loadfile, table, select
  4. = type, next, pairs, ipairs, loadfile, table, select
  5. local tonumber, tostring, math = tonumber, tostring, math
  6. local require = require
  7. local nxo = require "nixio"
  8. local nfs = require "nixio.fs"
  9. local ipc = require "luci.ip"
  10. local sys = require "luci.sys"
  11. local utl = require "luci.util"
  12. local dsp = require "luci.dispatcher"
  13. local uci = require "luci.model.uci"
  14. local lng = require "luci.i18n"
  15. local jsc = require "luci.jsonc"
  16. module "luci.model.network"
  17. IFACE_PATTERNS_VIRTUAL = { }
  18. IFACE_PATTERNS_IGNORE = { "^wmaster%d", "^wifi%d", "^hwsim%d", "^imq%d", "^ifb%d", "^mon%.wlan%d", "^sit%d", "^gre%d", "^gretap%d", "^ip6gre%d", "^ip6tnl%d", "^tunl%d", "^lo$" }
  19. IFACE_PATTERNS_WIRELESS = { "^wlan%d", "^wl%d", "^ath%d", "^%w+%.network%d" }
  20. protocol = utl.class()
  21. local _protocols = { }
  22. local _interfaces, _bridge, _switch, _tunnel, _swtopo
  23. local _ubusnetcache, _ubusdevcache, _ubuswificache
  24. local _uci
  25. function _filter(c, s, o, r)
  26. local val = _uci:get(c, s, o)
  27. if val then
  28. local l = { }
  29. if type(val) == "string" then
  30. for val in val:gmatch("%S+") do
  31. if val ~= r then
  32. l[#l+1] = val
  33. end
  34. end
  35. if #l > 0 then
  36. _uci:set(c, s, o, table.concat(l, " "))
  37. else
  38. _uci:delete(c, s, o)
  39. end
  40. elseif type(val) == "table" then
  41. for _, val in ipairs(val) do
  42. if val ~= r then
  43. l[#l+1] = val
  44. end
  45. end
  46. if #l > 0 then
  47. _uci:set(c, s, o, l)
  48. else
  49. _uci:delete(c, s, o)
  50. end
  51. end
  52. end
  53. end
  54. function _append(c, s, o, a)
  55. local val = _uci:get(c, s, o) or ""
  56. if type(val) == "string" then
  57. local l = { }
  58. for val in val:gmatch("%S+") do
  59. if val ~= a then
  60. l[#l+1] = val
  61. end
  62. end
  63. l[#l+1] = a
  64. _uci:set(c, s, o, table.concat(l, " "))
  65. elseif type(val) == "table" then
  66. local l = { }
  67. for _, val in ipairs(val) do
  68. if val ~= a then
  69. l[#l+1] = val
  70. end
  71. end
  72. l[#l+1] = a
  73. _uci:set(c, s, o, l)
  74. end
  75. end
  76. function _stror(s1, s2)
  77. if not s1 or #s1 == 0 then
  78. return s2 and #s2 > 0 and s2
  79. else
  80. return s1
  81. end
  82. end
  83. function _get(c, s, o)
  84. return _uci:get(c, s, o)
  85. end
  86. function _set(c, s, o, v)
  87. if v ~= nil then
  88. if type(v) == "boolean" then v = v and "1" or "0" end
  89. return _uci:set(c, s, o, v)
  90. else
  91. return _uci:delete(c, s, o)
  92. end
  93. end
  94. function _wifi_iface(x)
  95. local _, p
  96. for _, p in ipairs(IFACE_PATTERNS_WIRELESS) do
  97. if x:match(p) then
  98. return true
  99. end
  100. end
  101. return false
  102. end
  103. function _wifi_state(key, val, field)
  104. local radio, radiostate, ifc, ifcstate
  105. if not next(_ubuswificache) then
  106. _ubuswificache = utl.ubus("network.wireless", "status", {}) or {}
  107. -- workaround extended section format
  108. for radio, radiostate in pairs(_ubuswificache) do
  109. for ifc, ifcstate in pairs(radiostate.interfaces) do
  110. if ifcstate.section and ifcstate.section:sub(1, 1) == '@' then
  111. local s = _uci:get_all('wireless.%s' % ifcstate.section)
  112. if s then
  113. ifcstate.section = s['.name']
  114. end
  115. end
  116. end
  117. end
  118. end
  119. for radio, radiostate in pairs(_ubuswificache) do
  120. for ifc, ifcstate in pairs(radiostate.interfaces) do
  121. if ifcstate[key] == val then
  122. return ifcstate[field]
  123. end
  124. end
  125. end
  126. end
  127. function _wifi_lookup(ifn)
  128. -- got a radio#.network# pseudo iface, locate the corresponding section
  129. local radio, ifnidx = ifn:match("^(%w+)%.network(%d+)$")
  130. if radio and ifnidx then
  131. local sid = nil
  132. local num = 0
  133. ifnidx = tonumber(ifnidx)
  134. _uci:foreach("wireless", "wifi-iface",
  135. function(s)
  136. if s.device == radio then
  137. num = num + 1
  138. if num == ifnidx then
  139. sid = s['.name']
  140. return false
  141. end
  142. end
  143. end)
  144. return sid
  145. -- looks like wifi, try to locate the section via ubus state
  146. elseif _wifi_iface(ifn) then
  147. return _wifi_state("ifname", ifn, "section")
  148. end
  149. end
  150. function _iface_virtual(x)
  151. local _, p
  152. for _, p in ipairs(IFACE_PATTERNS_VIRTUAL) do
  153. if x:match(p) then
  154. return true
  155. end
  156. end
  157. return false
  158. end
  159. function _iface_ignore(x)
  160. local _, p
  161. for _, p in ipairs(IFACE_PATTERNS_IGNORE) do
  162. if x:match(p) then
  163. return true
  164. end
  165. end
  166. return false
  167. end
  168. function init(cursor)
  169. _uci = cursor or _uci or uci.cursor()
  170. _interfaces = { }
  171. _bridge = { }
  172. _switch = { }
  173. _tunnel = { }
  174. _swtopo = { }
  175. _ubusnetcache = { }
  176. _ubusdevcache = { }
  177. _ubuswificache = { }
  178. -- read interface information
  179. local n, i
  180. for n, i in ipairs(nxo.getifaddrs()) do
  181. local name = i.name:match("[^:]+")
  182. if _iface_virtual(name) then
  183. _tunnel[name] = true
  184. end
  185. if _tunnel[name] or not (_iface_ignore(name) or _iface_virtual(name)) then
  186. _interfaces[name] = _interfaces[name] or {
  187. idx = i.ifindex or n,
  188. name = name,
  189. rawname = i.name,
  190. flags = { },
  191. ipaddrs = { },
  192. ip6addrs = { }
  193. }
  194. if i.family == "packet" then
  195. _interfaces[name].flags = i.flags
  196. _interfaces[name].stats = i.data
  197. _interfaces[name].macaddr = i.addr
  198. elseif i.family == "inet" then
  199. _interfaces[name].ipaddrs[#_interfaces[name].ipaddrs+1] = ipc.IPv4(i.addr, i.netmask)
  200. elseif i.family == "inet6" then
  201. _interfaces[name].ip6addrs[#_interfaces[name].ip6addrs+1] = ipc.IPv6(i.addr, i.netmask)
  202. end
  203. end
  204. end
  205. -- read bridge informaton
  206. local b, l
  207. for l in utl.execi("brctl show") do
  208. if not l:match("STP") then
  209. local r = utl.split(l, "%s+", nil, true)
  210. if #r == 4 then
  211. b = {
  212. name = r[1],
  213. id = r[2],
  214. stp = r[3] == "yes",
  215. ifnames = { _interfaces[r[4]] }
  216. }
  217. if b.ifnames[1] then
  218. b.ifnames[1].bridge = b
  219. end
  220. _bridge[r[1]] = b
  221. elseif b then
  222. b.ifnames[#b.ifnames+1] = _interfaces[r[2]]
  223. b.ifnames[#b.ifnames].bridge = b
  224. end
  225. end
  226. end
  227. -- read switch topology
  228. local boardinfo = jsc.parse(nfs.readfile("/etc/board.json") or "")
  229. if type(boardinfo) == "table" and type(boardinfo.switch) == "table" then
  230. local switch, layout
  231. for switch, layout in pairs(boardinfo.switch) do
  232. if type(layout) == "table" and type(layout.ports) == "table" then
  233. local _, port
  234. local ports = { }
  235. local nports = { }
  236. local netdevs = { }
  237. for _, port in ipairs(layout.ports) do
  238. if type(port) == "table" and
  239. type(port.num) == "number" and
  240. (type(port.role) == "string" or
  241. type(port.device) == "string")
  242. then
  243. local spec = {
  244. num = port.num,
  245. role = port.role or "cpu",
  246. index = port.index or port.num
  247. }
  248. if port.device then
  249. spec.device = port.device
  250. spec.tagged = port.need_tag
  251. netdevs[tostring(port.num)] = port.device
  252. end
  253. ports[#ports+1] = spec
  254. if port.role then
  255. nports[port.role] = (nports[port.role] or 0) + 1
  256. end
  257. end
  258. end
  259. table.sort(ports, function(a, b)
  260. if a.role ~= b.role then
  261. return (a.role < b.role)
  262. end
  263. return (a.index < b.index)
  264. end)
  265. local pnum, role
  266. for _, port in ipairs(ports) do
  267. if port.role ~= role then
  268. role = port.role
  269. pnum = 1
  270. end
  271. if role == "cpu" then
  272. port.label = "CPU (%s)" % port.device
  273. elseif nports[role] > 1 then
  274. port.label = "%s %d" %{ role:upper(), pnum }
  275. pnum = pnum + 1
  276. else
  277. port.label = role:upper()
  278. end
  279. port.role = nil
  280. port.index = nil
  281. end
  282. _swtopo[switch] = {
  283. ports = ports,
  284. netdevs = netdevs
  285. }
  286. end
  287. end
  288. end
  289. return _M
  290. end
  291. function save(self, ...)
  292. _uci:save(...)
  293. _uci:load(...)
  294. end
  295. function commit(self, ...)
  296. _uci:commit(...)
  297. _uci:load(...)
  298. end
  299. function ifnameof(self, x)
  300. if utl.instanceof(x, interface) then
  301. return x:name()
  302. elseif utl.instanceof(x, protocol) then
  303. return x:ifname()
  304. elseif type(x) == "string" then
  305. return x:match("^[^:]+")
  306. end
  307. end
  308. function get_protocol(self, protoname, netname)
  309. local v = _protocols[protoname]
  310. if v then
  311. return v(netname or "__dummy__")
  312. end
  313. end
  314. function get_protocols(self)
  315. local p = { }
  316. local _, v
  317. for _, v in ipairs(_protocols) do
  318. p[#p+1] = v("__dummy__")
  319. end
  320. return p
  321. end
  322. function register_protocol(self, protoname)
  323. local proto = utl.class(protocol)
  324. function proto.__init__(self, name)
  325. self.sid = name
  326. end
  327. function proto.proto(self)
  328. return protoname
  329. end
  330. _protocols[#_protocols+1] = proto
  331. _protocols[protoname] = proto
  332. return proto
  333. end
  334. function register_pattern_virtual(self, pat)
  335. IFACE_PATTERNS_VIRTUAL[#IFACE_PATTERNS_VIRTUAL+1] = pat
  336. end
  337. function has_ipv6(self)
  338. return nfs.access("/proc/net/ipv6_route")
  339. end
  340. function add_network(self, n, options)
  341. local oldnet = self:get_network(n)
  342. if n and #n > 0 and n:match("^[a-zA-Z0-9_]+$") and not oldnet then
  343. if _uci:section("network", "interface", n, options) then
  344. return network(n)
  345. end
  346. elseif oldnet and oldnet:is_empty() then
  347. if options then
  348. local k, v
  349. for k, v in pairs(options) do
  350. oldnet:set(k, v)
  351. end
  352. end
  353. return oldnet
  354. end
  355. end
  356. function get_network(self, n)
  357. if n and _uci:get("network", n) == "interface" then
  358. return network(n)
  359. end
  360. end
  361. function get_networks(self)
  362. local nets = { }
  363. local nls = { }
  364. _uci:foreach("network", "interface",
  365. function(s)
  366. nls[s['.name']] = network(s['.name'])
  367. end)
  368. local n
  369. for n in utl.kspairs(nls) do
  370. nets[#nets+1] = nls[n]
  371. end
  372. return nets
  373. end
  374. function del_network(self, n)
  375. local r = _uci:delete("network", n)
  376. if r then
  377. _uci:delete_all("network", "alias",
  378. function(s) return (s.interface == n) end)
  379. _uci:delete_all("network", "route",
  380. function(s) return (s.interface == n) end)
  381. _uci:delete_all("network", "route6",
  382. function(s) return (s.interface == n) end)
  383. _uci:foreach("wireless", "wifi-iface",
  384. function(s)
  385. local net
  386. local rest = { }
  387. for net in utl.imatch(s.network) do
  388. if net ~= n then
  389. rest[#rest+1] = net
  390. end
  391. end
  392. if #rest > 0 then
  393. _uci:set("wireless", s['.name'], "network",
  394. table.concat(rest, " "))
  395. else
  396. _uci:delete("wireless", s['.name'], "network")
  397. end
  398. end)
  399. end
  400. return r
  401. end
  402. function rename_network(self, old, new)
  403. local r
  404. if new and #new > 0 and new:match("^[a-zA-Z0-9_]+$") and not self:get_network(new) then
  405. r = _uci:section("network", "interface", new, _uci:get_all("network", old))
  406. if r then
  407. _uci:foreach("network", "alias",
  408. function(s)
  409. if s.interface == old then
  410. _uci:set("network", s['.name'], "interface", new)
  411. end
  412. end)
  413. _uci:foreach("network", "route",
  414. function(s)
  415. if s.interface == old then
  416. _uci:set("network", s['.name'], "interface", new)
  417. end
  418. end)
  419. _uci:foreach("network", "route6",
  420. function(s)
  421. if s.interface == old then
  422. _uci:set("network", s['.name'], "interface", new)
  423. end
  424. end)
  425. _uci:foreach("wireless", "wifi-iface",
  426. function(s)
  427. local net
  428. local list = { }
  429. for net in utl.imatch(s.network) do
  430. if net == old then
  431. list[#list+1] = new
  432. else
  433. list[#list+1] = net
  434. end
  435. end
  436. if #list > 0 then
  437. _uci:set("wireless", s['.name'], "network",
  438. table.concat(list, " "))
  439. end
  440. end)
  441. _uci:delete("network", old)
  442. end
  443. end
  444. return r or false
  445. end
  446. function get_interface(self, i)
  447. if _interfaces[i] or _wifi_iface(i) then
  448. return interface(i)
  449. else
  450. local ifc
  451. local num = { }
  452. _uci:foreach("wireless", "wifi-iface",
  453. function(s)
  454. if s.device then
  455. num[s.device] = num[s.device] and num[s.device] + 1 or 1
  456. if s['.name'] == i then
  457. ifc = interface(
  458. "%s.network%d" %{s.device, num[s.device] })
  459. return false
  460. end
  461. end
  462. end)
  463. return ifc
  464. end
  465. end
  466. function get_interfaces(self)
  467. local iface
  468. local ifaces = { }
  469. local nfs = { }
  470. -- find normal interfaces
  471. _uci:foreach("network", "interface",
  472. function(s)
  473. for iface in utl.imatch(s.ifname) do
  474. if not _iface_ignore(iface) and not _iface_virtual(iface) and not _wifi_iface(iface) then
  475. nfs[iface] = interface(iface)
  476. end
  477. end
  478. end)
  479. for iface in utl.kspairs(_interfaces) do
  480. if not (nfs[iface] or _iface_ignore(iface) or _iface_virtual(iface) or _wifi_iface(iface)) then
  481. nfs[iface] = interface(iface)
  482. end
  483. end
  484. -- find vlan interfaces
  485. _uci:foreach("network", "switch_vlan",
  486. function(s)
  487. if type(s.ports) ~= "string" or
  488. type(s.device) ~= "string" or
  489. type(_swtopo[s.device]) ~= "table"
  490. then
  491. return
  492. end
  493. local pnum, ptag
  494. for pnum, ptag in s.ports:gmatch("(%d+)([tu]?)") do
  495. local netdev = _swtopo[s.device].netdevs[pnum]
  496. if netdev then
  497. if not nfs[netdev] then
  498. nfs[netdev] = interface(netdev)
  499. end
  500. _switch[netdev] = true
  501. if ptag == "t" then
  502. local vid = tonumber(s.vid or s.vlan)
  503. if vid ~= nil and vid >= 0 and vid <= 4095 then
  504. local iface = "%s.%d" %{ netdev, vid }
  505. if not nfs[iface] then
  506. nfs[iface] = interface(iface)
  507. end
  508. _switch[iface] = true
  509. end
  510. end
  511. end
  512. end
  513. end)
  514. for iface in utl.kspairs(nfs) do
  515. ifaces[#ifaces+1] = nfs[iface]
  516. end
  517. -- find wifi interfaces
  518. local num = { }
  519. local wfs = { }
  520. _uci:foreach("wireless", "wifi-iface",
  521. function(s)
  522. if s.device then
  523. num[s.device] = num[s.device] and num[s.device] + 1 or 1
  524. local i = "%s.network%d" %{ s.device, num[s.device] }
  525. wfs[i] = interface(i)
  526. end
  527. end)
  528. for iface in utl.kspairs(wfs) do
  529. ifaces[#ifaces+1] = wfs[iface]
  530. end
  531. return ifaces
  532. end
  533. function ignore_interface(self, x)
  534. return _iface_ignore(x)
  535. end
  536. function get_wifidev(self, dev)
  537. if _uci:get("wireless", dev) == "wifi-device" then
  538. return wifidev(dev)
  539. end
  540. end
  541. function get_wifidevs(self)
  542. local devs = { }
  543. local wfd = { }
  544. _uci:foreach("wireless", "wifi-device",
  545. function(s) wfd[#wfd+1] = s['.name'] end)
  546. local dev
  547. for _, dev in utl.vspairs(wfd) do
  548. devs[#devs+1] = wifidev(dev)
  549. end
  550. return devs
  551. end
  552. function get_wifinet(self, net)
  553. local wnet = _wifi_lookup(net)
  554. if wnet then
  555. return wifinet(wnet)
  556. end
  557. end
  558. function add_wifinet(self, net, options)
  559. if type(options) == "table" and options.device and
  560. _uci:get("wireless", options.device) == "wifi-device"
  561. then
  562. local wnet = _uci:section("wireless", "wifi-iface", nil, options)
  563. return wifinet(wnet)
  564. end
  565. end
  566. function del_wifinet(self, net)
  567. local wnet = _wifi_lookup(net)
  568. if wnet then
  569. _uci:delete("wireless", wnet)
  570. return true
  571. end
  572. return false
  573. end
  574. function get_status_by_route(self, addr, mask)
  575. local _, object
  576. for _, object in ipairs(utl.ubus()) do
  577. local net = object:match("^network%.interface%.(.+)")
  578. if net then
  579. local s = utl.ubus(object, "status", {})
  580. if s and s.route then
  581. local rt
  582. for _, rt in ipairs(s.route) do
  583. if not rt.table and rt.target == addr and rt.mask == mask then
  584. return net, s
  585. end
  586. end
  587. end
  588. end
  589. end
  590. end
  591. function get_status_by_address(self, addr)
  592. local _, object
  593. for _, object in ipairs(utl.ubus()) do
  594. local net = object:match("^network%.interface%.(.+)")
  595. if net then
  596. local s = utl.ubus(object, "status", {})
  597. if s and s['ipv4-address'] then
  598. local a
  599. for _, a in ipairs(s['ipv4-address']) do
  600. if a.address == addr then
  601. return net, s
  602. end
  603. end
  604. end
  605. if s and s['ipv6-address'] then
  606. local a
  607. for _, a in ipairs(s['ipv6-address']) do
  608. if a.address == addr then
  609. return net, s
  610. end
  611. end
  612. end
  613. end
  614. end
  615. end
  616. function get_wannet(self)
  617. local net, stat = self:get_status_by_route("0.0.0.0", 0)
  618. return net and network(net, stat.proto)
  619. end
  620. function get_wandev(self)
  621. local _, stat = self:get_status_by_route("0.0.0.0", 0)
  622. return stat and interface(stat.l3_device or stat.device)
  623. end
  624. function get_wan6net(self)
  625. local net, stat = self:get_status_by_route("::", 0)
  626. return net and network(net, stat.proto)
  627. end
  628. function get_wan6dev(self)
  629. local _, stat = self:get_status_by_route("::", 0)
  630. return stat and interface(stat.l3_device or stat.device)
  631. end
  632. function get_switch_topologies(self)
  633. return _swtopo
  634. end
  635. function network(name, proto)
  636. if name then
  637. local p = proto or _uci:get("network", name, "proto")
  638. local c = p and _protocols[p] or protocol
  639. return c(name)
  640. end
  641. end
  642. function protocol.__init__(self, name)
  643. self.sid = name
  644. end
  645. function protocol._get(self, opt)
  646. local v = _uci:get("network", self.sid, opt)
  647. if type(v) == "table" then
  648. return table.concat(v, " ")
  649. end
  650. return v or ""
  651. end
  652. function protocol._ubus(self, field)
  653. if not _ubusnetcache[self.sid] then
  654. _ubusnetcache[self.sid] = utl.ubus("network.interface.%s" % self.sid,
  655. "status", { })
  656. end
  657. if _ubusnetcache[self.sid] and field then
  658. return _ubusnetcache[self.sid][field]
  659. end
  660. return _ubusnetcache[self.sid]
  661. end
  662. function protocol.get(self, opt)
  663. return _get("network", self.sid, opt)
  664. end
  665. function protocol.set(self, opt, val)
  666. return _set("network", self.sid, opt, val)
  667. end
  668. function protocol.ifname(self)
  669. local ifname
  670. if self:is_floating() then
  671. ifname = self:_ubus("l3_device")
  672. else
  673. ifname = self:_ubus("device")
  674. end
  675. if not ifname then
  676. local num = { }
  677. _uci:foreach("wireless", "wifi-iface",
  678. function(s)
  679. if s.device then
  680. num[s.device] = num[s.device]
  681. and num[s.device] + 1 or 1
  682. local net
  683. for net in utl.imatch(s.network) do
  684. if net == self.sid then
  685. ifname = "%s.network%d" %{ s.device, num[s.device] }
  686. return false
  687. end
  688. end
  689. end
  690. end)
  691. end
  692. return ifname
  693. end
  694. function protocol.proto(self)
  695. return "none"
  696. end
  697. function protocol.get_i18n(self)
  698. local p = self:proto()
  699. if p == "none" then
  700. return lng.translate("Unmanaged")
  701. elseif p == "static" then
  702. return lng.translate("Static address")
  703. elseif p == "dhcp" then
  704. return lng.translate("DHCP client")
  705. else
  706. return lng.translate("Unknown")
  707. end
  708. end
  709. function protocol.type(self)
  710. return self:_get("type")
  711. end
  712. function protocol.name(self)
  713. return self.sid
  714. end
  715. function protocol.uptime(self)
  716. return self:_ubus("uptime") or 0
  717. end
  718. function protocol.expires(self)
  719. local u = self:_ubus("uptime")
  720. local d = self:_ubus("data")
  721. if type(u) == "number" and type(d) == "table" and
  722. type(d.leasetime) == "number"
  723. then
  724. local r = (d.leasetime - (u % d.leasetime))
  725. return r > 0 and r or 0
  726. end
  727. return -1
  728. end
  729. function protocol.metric(self)
  730. return self:_ubus("metric") or 0
  731. end
  732. function protocol.ipaddr(self)
  733. local addrs = self:_ubus("ipv4-address")
  734. return addrs and #addrs > 0 and addrs[1].address
  735. end
  736. function protocol.ipaddrs(self)
  737. local addrs = self:_ubus("ipv4-address")
  738. local rv = { }
  739. if type(addrs) == "table" then
  740. local n, addr
  741. for n, addr in ipairs(addrs) do
  742. rv[#rv+1] = "%s/%d" %{ addr.address, addr.mask }
  743. end
  744. end
  745. return rv
  746. end
  747. function protocol.netmask(self)
  748. local addrs = self:_ubus("ipv4-address")
  749. return addrs and #addrs > 0 and
  750. ipc.IPv4("0.0.0.0/%d" % addrs[1].mask):mask():string()
  751. end
  752. function protocol.gwaddr(self)
  753. local _, route
  754. for _, route in ipairs(self:_ubus("route") or { }) do
  755. if route.target == "0.0.0.0" and route.mask == 0 then
  756. return route.nexthop
  757. end
  758. end
  759. end
  760. function protocol.dnsaddrs(self)
  761. local dns = { }
  762. local _, addr
  763. for _, addr in ipairs(self:_ubus("dns-server") or { }) do
  764. if not addr:match(":") then
  765. dns[#dns+1] = addr
  766. end
  767. end
  768. return dns
  769. end
  770. function protocol.ip6addr(self)
  771. local addrs = self:_ubus("ipv6-address")
  772. if addrs and #addrs > 0 then
  773. return "%s/%d" %{ addrs[1].address, addrs[1].mask }
  774. else
  775. addrs = self:_ubus("ipv6-prefix-assignment")
  776. if addrs and #addrs > 0 then
  777. return "%s/%d" %{ addrs[1].address, addrs[1].mask }
  778. end
  779. end
  780. end
  781. function protocol.ip6addrs(self)
  782. local addrs = self:_ubus("ipv6-address")
  783. local rv = { }
  784. local n, addr
  785. if type(addrs) == "table" then
  786. for n, addr in ipairs(addrs) do
  787. rv[#rv+1] = "%s/%d" %{ addr.address, addr.mask }
  788. end
  789. end
  790. addrs = self:_ubus("ipv6-prefix-assignment")
  791. if type(addrs) == "table" then
  792. for n, addr in ipairs(addrs) do
  793. rv[#rv+1] = "%s1/%d" %{ addr.address, addr.mask }
  794. end
  795. end
  796. return rv
  797. end
  798. function protocol.gw6addr(self)
  799. local _, route
  800. for _, route in ipairs(self:_ubus("route") or { }) do
  801. if route.target == "::" and route.mask == 0 then
  802. return ipc.IPv6(route.nexthop):string()
  803. end
  804. end
  805. end
  806. function protocol.dns6addrs(self)
  807. local dns = { }
  808. local _, addr
  809. for _, addr in ipairs(self:_ubus("dns-server") or { }) do
  810. if addr:match(":") then
  811. dns[#dns+1] = addr
  812. end
  813. end
  814. return dns
  815. end
  816. function protocol.ip6prefix(self)
  817. local prefix = self:_ubus("ipv6-prefix")
  818. if prefix and #prefix > 0 then
  819. return "%s/%d" %{ prefix[1].address, prefix[1].mask }
  820. end
  821. end
  822. function protocol.is_bridge(self)
  823. return (not self:is_virtual() and self:type() == "bridge")
  824. end
  825. function protocol.opkg_package(self)
  826. return nil
  827. end
  828. function protocol.is_installed(self)
  829. return true
  830. end
  831. function protocol.is_virtual(self)
  832. return false
  833. end
  834. function protocol.is_floating(self)
  835. return false
  836. end
  837. function protocol.is_empty(self)
  838. if self:is_floating() then
  839. return false
  840. else
  841. local rv = true
  842. if (self:_get("ifname") or ""):match("%S+") then
  843. rv = false
  844. end
  845. _uci:foreach("wireless", "wifi-iface",
  846. function(s)
  847. local n
  848. for n in utl.imatch(s.network) do
  849. if n == self.sid then
  850. rv = false
  851. return false
  852. end
  853. end
  854. end)
  855. return rv
  856. end
  857. end
  858. function protocol.add_interface(self, ifname)
  859. ifname = _M:ifnameof(ifname)
  860. if ifname and not self:is_floating() then
  861. -- if its a wifi interface, change its network option
  862. local wif = _wifi_lookup(ifname)
  863. if wif then
  864. _append("wireless", wif, "network", self.sid)
  865. -- add iface to our iface list
  866. else
  867. _append("network", self.sid, "ifname", ifname)
  868. end
  869. end
  870. end
  871. function protocol.del_interface(self, ifname)
  872. ifname = _M:ifnameof(ifname)
  873. if ifname and not self:is_floating() then
  874. -- if its a wireless interface, clear its network option
  875. local wif = _wifi_lookup(ifname)
  876. if wif then _filter("wireless", wif, "network", self.sid) end
  877. -- remove the interface
  878. _filter("network", self.sid, "ifname", ifname)
  879. end
  880. end
  881. function protocol.get_interface(self)
  882. if self:is_virtual() then
  883. _tunnel[self:proto() .. "-" .. self.sid] = true
  884. return interface(self:proto() .. "-" .. self.sid, self)
  885. elseif self:is_bridge() then
  886. _bridge["br-" .. self.sid] = true
  887. return interface("br-" .. self.sid, self)
  888. else
  889. local ifn = nil
  890. local num = { }
  891. for ifn in utl.imatch(_uci:get("network", self.sid, "ifname")) do
  892. ifn = ifn:match("^[^:/]+")
  893. return ifn and interface(ifn, self)
  894. end
  895. ifn = nil
  896. _uci:foreach("wireless", "wifi-iface",
  897. function(s)
  898. if s.device then
  899. num[s.device] = num[s.device] and num[s.device] + 1 or 1
  900. local net
  901. for net in utl.imatch(s.network) do
  902. if net == self.sid then
  903. ifn = "%s.network%d" %{ s.device, num[s.device] }
  904. return false
  905. end
  906. end
  907. end
  908. end)
  909. return ifn and interface(ifn, self)
  910. end
  911. end
  912. function protocol.get_interfaces(self)
  913. if self:is_bridge() or (self:is_virtual() and not self:is_floating()) then
  914. local ifaces = { }
  915. local ifn
  916. local nfs = { }
  917. for ifn in utl.imatch(self:get("ifname")) do
  918. ifn = ifn:match("^[^:/]+")
  919. nfs[ifn] = interface(ifn, self)
  920. end
  921. for ifn in utl.kspairs(nfs) do
  922. ifaces[#ifaces+1] = nfs[ifn]
  923. end
  924. local num = { }
  925. local wfs = { }
  926. _uci:foreach("wireless", "wifi-iface",
  927. function(s)
  928. if s.device then
  929. num[s.device] = num[s.device] and num[s.device] + 1 or 1
  930. local net
  931. for net in utl.imatch(s.network) do
  932. if net == self.sid then
  933. ifn = "%s.network%d" %{ s.device, num[s.device] }
  934. wfs[ifn] = interface(ifn, self)
  935. end
  936. end
  937. end
  938. end)
  939. for ifn in utl.kspairs(wfs) do
  940. ifaces[#ifaces+1] = wfs[ifn]
  941. end
  942. return ifaces
  943. end
  944. end
  945. function protocol.contains_interface(self, ifname)
  946. ifname = _M:ifnameof(ifname)
  947. if not ifname then
  948. return false
  949. elseif self:is_virtual() and self:proto() .. "-" .. self.sid == ifname then
  950. return true
  951. elseif self:is_bridge() and "br-" .. self.sid == ifname then
  952. return true
  953. else
  954. local ifn
  955. for ifn in utl.imatch(self:get("ifname")) do
  956. ifn = ifn:match("[^:]+")
  957. if ifn == ifname then
  958. return true
  959. end
  960. end
  961. local wif = _wifi_lookup(ifname)
  962. if wif then
  963. local n
  964. for n in utl.imatch(_uci:get("wireless", wif, "network")) do
  965. if n == self.sid then
  966. return true
  967. end
  968. end
  969. end
  970. end
  971. return false
  972. end
  973. function protocol.adminlink(self)
  974. return dsp.build_url("admin", "network", "network", self.sid)
  975. end
  976. interface = utl.class()
  977. function interface.__init__(self, ifname, network)
  978. local wif = _wifi_lookup(ifname)
  979. if wif then
  980. self.wif = wifinet(wif)
  981. self.ifname = _wifi_state("section", wif, "ifname")
  982. end
  983. self.ifname = self.ifname or ifname
  984. self.dev = _interfaces[self.ifname]
  985. self.network = network
  986. end
  987. function interface._ubus(self, field)
  988. if not _ubusdevcache[self.ifname] then
  989. _ubusdevcache[self.ifname] = utl.ubus("network.device", "status",
  990. { name = self.ifname })
  991. end
  992. if _ubusdevcache[self.ifname] and field then
  993. return _ubusdevcache[self.ifname][field]
  994. end
  995. return _ubusdevcache[self.ifname]
  996. end
  997. function interface.name(self)
  998. return self.wif and self.wif:ifname() or self.ifname
  999. end
  1000. function interface.mac(self)
  1001. local mac = self:_ubus("macaddr")
  1002. return mac and mac:upper()
  1003. end
  1004. function interface.ipaddrs(self)
  1005. return self.dev and self.dev.ipaddrs or { }
  1006. end
  1007. function interface.ip6addrs(self)
  1008. return self.dev and self.dev.ip6addrs or { }
  1009. end
  1010. function interface.type(self)
  1011. if self.wif or _wifi_iface(self.ifname) then
  1012. return "wifi"
  1013. elseif _bridge[self.ifname] then
  1014. return "bridge"
  1015. elseif _tunnel[self.ifname] then
  1016. return "tunnel"
  1017. elseif self.ifname:match("%.") then
  1018. return "vlan"
  1019. elseif _switch[self.ifname] then
  1020. return "switch"
  1021. else
  1022. return "ethernet"
  1023. end
  1024. end
  1025. function interface.shortname(self)
  1026. if self.wif then
  1027. return self.wif:shortname()
  1028. else
  1029. return self.ifname
  1030. end
  1031. end
  1032. function interface.get_i18n(self)
  1033. if self.wif then
  1034. return "%s: %s %q" %{
  1035. lng.translate("Wireless Network"),
  1036. self.wif:active_mode(),
  1037. self.wif:active_ssid() or self.wif:active_bssid() or self.wif:id()
  1038. }
  1039. else
  1040. return "%s: %q" %{ self:get_type_i18n(), self:name() }
  1041. end
  1042. end
  1043. function interface.get_type_i18n(self)
  1044. local x = self:type()
  1045. if x == "wifi" then
  1046. return lng.translate("Wireless Adapter")
  1047. elseif x == "bridge" then
  1048. return lng.translate("Bridge")
  1049. elseif x == "switch" then
  1050. return lng.translate("Ethernet Switch")
  1051. elseif x == "vlan" then
  1052. if _switch[self.ifname] then
  1053. return lng.translate("Switch VLAN")
  1054. else
  1055. return lng.translate("Software VLAN")
  1056. end
  1057. elseif x == "tunnel" then
  1058. return lng.translate("Tunnel Interface")
  1059. else
  1060. return lng.translate("Ethernet Adapter")
  1061. end
  1062. end
  1063. function interface.adminlink(self)
  1064. if self.wif then
  1065. return self.wif:adminlink()
  1066. end
  1067. end
  1068. function interface.ports(self)
  1069. local members = self:_ubus("bridge-members")
  1070. if members then
  1071. local _, iface
  1072. local ifaces = { }
  1073. for _, iface in ipairs(members) do
  1074. ifaces[#ifaces+1] = interface(iface)
  1075. end
  1076. end
  1077. end
  1078. function interface.bridge_id(self)
  1079. if self.br then
  1080. return self.br.id
  1081. else
  1082. return nil
  1083. end
  1084. end
  1085. function interface.bridge_stp(self)
  1086. if self.br then
  1087. return self.br.stp
  1088. else
  1089. return false
  1090. end
  1091. end
  1092. function interface.is_up(self)
  1093. return self:_ubus("up") or false
  1094. end
  1095. function interface.is_bridge(self)
  1096. return (self:type() == "bridge")
  1097. end
  1098. function interface.is_bridgeport(self)
  1099. return self.dev and self.dev.bridge and true or false
  1100. end
  1101. function interface.tx_bytes(self)
  1102. local stat = self:_ubus("statistics")
  1103. return stat and stat.tx_bytes or 0
  1104. end
  1105. function interface.rx_bytes(self)
  1106. local stat = self:_ubus("statistics")
  1107. return stat and stat.rx_bytes or 0
  1108. end
  1109. function interface.tx_packets(self)
  1110. local stat = self:_ubus("statistics")
  1111. return stat and stat.tx_packets or 0
  1112. end
  1113. function interface.rx_packets(self)
  1114. local stat = self:_ubus("statistics")
  1115. return stat and stat.rx_packets or 0
  1116. end
  1117. function interface.get_network(self)
  1118. return self:get_networks()[1]
  1119. end
  1120. function interface.get_networks(self)
  1121. if not self.networks then
  1122. local nets = { }
  1123. local _, net
  1124. for _, net in ipairs(_M:get_networks()) do
  1125. if net:contains_interface(self.ifname) or
  1126. net:ifname() == self.ifname
  1127. then
  1128. nets[#nets+1] = net
  1129. end
  1130. end
  1131. table.sort(nets, function(a, b) return a.sid < b.sid end)
  1132. self.networks = nets
  1133. return nets
  1134. else
  1135. return self.networks
  1136. end
  1137. end
  1138. function interface.get_wifinet(self)
  1139. return self.wif
  1140. end
  1141. wifidev = utl.class()
  1142. function wifidev.__init__(self, dev)
  1143. self.sid = dev
  1144. self.iwinfo = dev and sys.wifi.getiwinfo(dev) or { }
  1145. end
  1146. function wifidev.get(self, opt)
  1147. return _get("wireless", self.sid, opt)
  1148. end
  1149. function wifidev.set(self, opt, val)
  1150. return _set("wireless", self.sid, opt, val)
  1151. end
  1152. function wifidev.name(self)
  1153. return self.sid
  1154. end
  1155. function wifidev.hwmodes(self)
  1156. local l = self.iwinfo.hwmodelist
  1157. if l and next(l) then
  1158. return l
  1159. else
  1160. return { b = true, g = true }
  1161. end
  1162. end
  1163. function wifidev.get_i18n(self)
  1164. local t = "Generic"
  1165. if self.iwinfo.type == "wl" then
  1166. t = "Broadcom"
  1167. end
  1168. local m = ""
  1169. local l = self:hwmodes()
  1170. if l.a then m = m .. "a" end
  1171. if l.b then m = m .. "b" end
  1172. if l.g then m = m .. "g" end
  1173. if l.n then m = m .. "n" end
  1174. if l.ac then m = "ac" end
  1175. return "%s 802.11%s Wireless Controller (%s)" %{ t, m, self:name() }
  1176. end
  1177. function wifidev.is_up(self)
  1178. if _ubuswificache[self.sid] then
  1179. return (_ubuswificache[self.sid].up == true)
  1180. end
  1181. return false
  1182. end
  1183. function wifidev.get_wifinet(self, net)
  1184. if _uci:get("wireless", net) == "wifi-iface" then
  1185. return wifinet(net)
  1186. else
  1187. local wnet = _wifi_lookup(net)
  1188. if wnet then
  1189. return wifinet(wnet)
  1190. end
  1191. end
  1192. end
  1193. function wifidev.get_wifinets(self)
  1194. local nets = { }
  1195. _uci:foreach("wireless", "wifi-iface",
  1196. function(s)
  1197. if s.device == self.sid then
  1198. nets[#nets+1] = wifinet(s['.name'])
  1199. end
  1200. end)
  1201. return nets
  1202. end
  1203. function wifidev.add_wifinet(self, options)
  1204. options = options or { }
  1205. options.device = self.sid
  1206. local wnet = _uci:section("wireless", "wifi-iface", nil, options)
  1207. if wnet then
  1208. return wifinet(wnet, options)
  1209. end
  1210. end
  1211. function wifidev.del_wifinet(self, net)
  1212. if utl.instanceof(net, wifinet) then
  1213. net = net.sid
  1214. elseif _uci:get("wireless", net) ~= "wifi-iface" then
  1215. net = _wifi_lookup(net)
  1216. end
  1217. if net and _uci:get("wireless", net, "device") == self.sid then
  1218. _uci:delete("wireless", net)
  1219. return true
  1220. end
  1221. return false
  1222. end
  1223. wifinet = utl.class()
  1224. function wifinet.__init__(self, net, data)
  1225. self.sid = net
  1226. local n = 0
  1227. local num = { }
  1228. local netid, sid
  1229. _uci:foreach("wireless", "wifi-iface",
  1230. function(s)
  1231. n = n + 1
  1232. if s.device then
  1233. num[s.device] = num[s.device] and num[s.device] + 1 or 1
  1234. if s['.name'] == self.sid then
  1235. sid = "@wifi-iface[%d]" % n
  1236. netid = "%s.network%d" %{ s.device, num[s.device] }
  1237. return false
  1238. end
  1239. end
  1240. end)
  1241. if sid then
  1242. local _, k, r, i
  1243. for k, r in pairs(_ubuswificache) do
  1244. if type(r) == "table" and
  1245. type(r.interfaces) == "table"
  1246. then
  1247. for _, i in ipairs(r.interfaces) do
  1248. if type(i) == "table" and i.section == sid then
  1249. self._ubusdata = {
  1250. radio = k,
  1251. dev = r,
  1252. net = i
  1253. }
  1254. end
  1255. end
  1256. end
  1257. end
  1258. end
  1259. local dev = _wifi_state("section", self.sid, "ifname") or netid
  1260. self.netid = netid
  1261. self.wdev = dev
  1262. self.iwinfo = dev and sys.wifi.getiwinfo(dev) or { }
  1263. end
  1264. function wifinet.ubus(self, ...)
  1265. local n, v = self._ubusdata
  1266. for n = 1, select('#', ...) do
  1267. if type(v) == "table" then
  1268. v = v[select(n, ...)]
  1269. else
  1270. return nil
  1271. end
  1272. end
  1273. return v
  1274. end
  1275. function wifinet.get(self, opt)
  1276. return _get("wireless", self.sid, opt)
  1277. end
  1278. function wifinet.set(self, opt, val)
  1279. return _set("wireless", self.sid, opt, val)
  1280. end
  1281. function wifinet.mode(self)
  1282. return self:ubus("net", "config", "mode") or self:get("mode") or "ap"
  1283. end
  1284. function wifinet.ssid(self)
  1285. return self:ubus("net", "config", "ssid") or self:get("ssid")
  1286. end
  1287. function wifinet.bssid(self)
  1288. return self:ubus("net", "config", "bssid") or self:get("bssid")
  1289. end
  1290. function wifinet.network(self)
  1291. local net, networks = nil, { }
  1292. for net in utl.imatch(self:ubus("net", "config", "network") or self:get("network")) do
  1293. networks[#networks+1] = net
  1294. end
  1295. return networks
  1296. end
  1297. function wifinet.id(self)
  1298. return self.netid
  1299. end
  1300. function wifinet.name(self)
  1301. return self.sid
  1302. end
  1303. function wifinet.ifname(self)
  1304. local ifname = self:ubus("net", "ifname") or self.iwinfo.ifname
  1305. if not ifname or ifname:match("^wifi%d") or ifname:match("^radio%d") then
  1306. ifname = self.wdev
  1307. end
  1308. return ifname
  1309. end
  1310. function wifinet.get_device(self)
  1311. local dev = self:ubus("radio") or self:get("device")
  1312. return dev and wifidev(dev) or nil
  1313. end
  1314. function wifinet.is_up(self)
  1315. local ifc = self:get_interface()
  1316. return (ifc and ifc:is_up() or false)
  1317. end
  1318. function wifinet.active_mode(self)
  1319. local m = self.iwinfo.mode or self:ubus("net", "config", "mode") or self:get("mode") or "ap"
  1320. if m == "ap" then m = "Master"
  1321. elseif m == "sta" then m = "Client"
  1322. elseif m == "adhoc" then m = "Ad-Hoc"
  1323. elseif m == "mesh" then m = "Mesh"
  1324. elseif m == "monitor" then m = "Monitor"
  1325. end
  1326. return m
  1327. end
  1328. function wifinet.active_mode_i18n(self)
  1329. return lng.translate(self:active_mode())
  1330. end
  1331. function wifinet.active_ssid(self)
  1332. return self.iwinfo.ssid or self:ubus("net", "config", "ssid") or self:get("ssid")
  1333. end
  1334. function wifinet.active_bssid(self)
  1335. return self.iwinfo.bssid or self:ubus("net", "config", "bssid") or self:get("bssid")
  1336. end
  1337. function wifinet.active_encryption(self)
  1338. local enc = self.iwinfo and self.iwinfo.encryption
  1339. return enc and enc.description or "-"
  1340. end
  1341. function wifinet.assoclist(self)
  1342. return self.iwinfo.assoclist or { }
  1343. end
  1344. function wifinet.frequency(self)
  1345. local freq = self.iwinfo.frequency
  1346. if freq and freq > 0 then
  1347. return "%.03f" % (freq / 1000)
  1348. end
  1349. end
  1350. function wifinet.bitrate(self)
  1351. local rate = self.iwinfo.bitrate
  1352. if rate and rate > 0 then
  1353. return (rate / 1000)
  1354. end
  1355. end
  1356. function wifinet.channel(self)
  1357. return self.iwinfo.channel or self:ubus("dev", "config", "channel") or
  1358. tonumber(self:get("channel"))
  1359. end
  1360. function wifinet.signal(self)
  1361. return self.iwinfo.signal or 0
  1362. end
  1363. function wifinet.noise(self)
  1364. return self.iwinfo.noise or 0
  1365. end
  1366. function wifinet.country(self)
  1367. return self.iwinfo.country or self:ubus("dev", "config", "country") or "00"
  1368. end
  1369. function wifinet.txpower(self)
  1370. local pwr = (self.iwinfo.txpower or 0)
  1371. return pwr + self:txpower_offset()
  1372. end
  1373. function wifinet.txpower_offset(self)
  1374. return self.iwinfo.txpower_offset or 0
  1375. end
  1376. function wifinet.signal_level(self, s, n)
  1377. if self:active_bssid() ~= "00:00:00:00:00:00" then
  1378. local signal = s or self:signal()
  1379. local noise = n or self:noise()
  1380. if signal < 0 and noise < 0 then
  1381. local snr = -1 * (noise - signal)
  1382. return math.floor(snr / 5)
  1383. else
  1384. return 0
  1385. end
  1386. else
  1387. return -1
  1388. end
  1389. end
  1390. function wifinet.signal_percent(self)
  1391. local qc = self.iwinfo.quality or 0
  1392. local qm = self.iwinfo.quality_max or 0
  1393. if qc > 0 and qm > 0 then
  1394. return math.floor((100 / qm) * qc)
  1395. else
  1396. return 0
  1397. end
  1398. end
  1399. function wifinet.shortname(self)
  1400. return "%s %q" %{
  1401. lng.translate(self:active_mode()),
  1402. self:active_ssid() or self:active_bssid() or self:id()
  1403. }
  1404. end
  1405. function wifinet.get_i18n(self)
  1406. return "%s: %s %q (%s)" %{
  1407. lng.translate("Wireless Network"),
  1408. lng.translate(self:active_mode()),
  1409. self:active_ssid() or self:active_bssid() or self:id(),
  1410. self:ifname()
  1411. }
  1412. end
  1413. function wifinet.adminlink(self)
  1414. return dsp.build_url("admin", "network", "wireless", self.netid)
  1415. end
  1416. function wifinet.get_network(self)
  1417. return self:get_networks()[1]
  1418. end
  1419. function wifinet.get_networks(self)
  1420. local nets = { }
  1421. local net
  1422. for net in utl.imatch(self:ubus("net", "config", "network") or self:get("network")) do
  1423. if _uci:get("network", net) == "interface" then
  1424. nets[#nets+1] = network(net)
  1425. end
  1426. end
  1427. table.sort(nets, function(a, b) return a.sid < b.sid end)
  1428. return nets
  1429. end
  1430. function wifinet.get_interface(self)
  1431. return interface(self:ifname())
  1432. end
  1433. -- setup base protocols
  1434. _M:register_protocol("static")
  1435. _M:register_protocol("dhcp")
  1436. _M:register_protocol("none")
  1437. -- load protocol extensions
  1438. local exts = nfs.dir(utl.libpath() .. "/model/network")
  1439. if exts then
  1440. local ext
  1441. for ext in exts do
  1442. if ext:match("%.lua$") then
  1443. require("luci.model.network." .. ext:gsub("%.lua$", ""))
  1444. end
  1445. end
  1446. end