1
0

network.lua 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707
  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. elseif self.iwinfo.type == "madwifi" then
  1168. t = "Atheros"
  1169. end
  1170. local m = ""
  1171. local l = self:hwmodes()
  1172. if l.a then m = m .. "a" end
  1173. if l.b then m = m .. "b" end
  1174. if l.g then m = m .. "g" end
  1175. if l.n then m = m .. "n" end
  1176. if l.ac then m = "ac" end
  1177. return "%s 802.11%s Wireless Controller (%s)" %{ t, m, self:name() }
  1178. end
  1179. function wifidev.is_up(self)
  1180. if _ubuswificache[self.sid] then
  1181. return (_ubuswificache[self.sid].up == true)
  1182. end
  1183. return false
  1184. end
  1185. function wifidev.get_wifinet(self, net)
  1186. if _uci:get("wireless", net) == "wifi-iface" then
  1187. return wifinet(net)
  1188. else
  1189. local wnet = _wifi_lookup(net)
  1190. if wnet then
  1191. return wifinet(wnet)
  1192. end
  1193. end
  1194. end
  1195. function wifidev.get_wifinets(self)
  1196. local nets = { }
  1197. _uci:foreach("wireless", "wifi-iface",
  1198. function(s)
  1199. if s.device == self.sid then
  1200. nets[#nets+1] = wifinet(s['.name'])
  1201. end
  1202. end)
  1203. return nets
  1204. end
  1205. function wifidev.add_wifinet(self, options)
  1206. options = options or { }
  1207. options.device = self.sid
  1208. local wnet = _uci:section("wireless", "wifi-iface", nil, options)
  1209. if wnet then
  1210. return wifinet(wnet, options)
  1211. end
  1212. end
  1213. function wifidev.del_wifinet(self, net)
  1214. if utl.instanceof(net, wifinet) then
  1215. net = net.sid
  1216. elseif _uci:get("wireless", net) ~= "wifi-iface" then
  1217. net = _wifi_lookup(net)
  1218. end
  1219. if net and _uci:get("wireless", net, "device") == self.sid then
  1220. _uci:delete("wireless", net)
  1221. return true
  1222. end
  1223. return false
  1224. end
  1225. wifinet = utl.class()
  1226. function wifinet.__init__(self, net, data)
  1227. self.sid = net
  1228. local n = 0
  1229. local num = { }
  1230. local netid, sid
  1231. _uci:foreach("wireless", "wifi-iface",
  1232. function(s)
  1233. n = n + 1
  1234. if s.device then
  1235. num[s.device] = num[s.device] and num[s.device] + 1 or 1
  1236. if s['.name'] == self.sid then
  1237. sid = "@wifi-iface[%d]" % n
  1238. netid = "%s.network%d" %{ s.device, num[s.device] }
  1239. return false
  1240. end
  1241. end
  1242. end)
  1243. if sid then
  1244. local _, k, r, i
  1245. for k, r in pairs(_ubuswificache) do
  1246. if type(r) == "table" and
  1247. type(r.interfaces) == "table"
  1248. then
  1249. for _, i in ipairs(r.interfaces) do
  1250. if type(i) == "table" and i.section == sid then
  1251. self._ubusdata = {
  1252. radio = k,
  1253. dev = r,
  1254. net = i
  1255. }
  1256. end
  1257. end
  1258. end
  1259. end
  1260. end
  1261. local dev = _wifi_state("section", self.sid, "ifname") or netid
  1262. self.netid = netid
  1263. self.wdev = dev
  1264. self.iwinfo = dev and sys.wifi.getiwinfo(dev) or { }
  1265. end
  1266. function wifinet.ubus(self, ...)
  1267. local n, v = self._ubusdata
  1268. for n = 1, select('#', ...) do
  1269. if type(v) == "table" then
  1270. v = v[select(n, ...)]
  1271. else
  1272. return nil
  1273. end
  1274. end
  1275. return v
  1276. end
  1277. function wifinet.get(self, opt)
  1278. return _get("wireless", self.sid, opt)
  1279. end
  1280. function wifinet.set(self, opt, val)
  1281. return _set("wireless", self.sid, opt, val)
  1282. end
  1283. function wifinet.mode(self)
  1284. return self:ubus("net", "config", "mode") or self:get("mode") or "ap"
  1285. end
  1286. function wifinet.ssid(self)
  1287. return self:ubus("net", "config", "ssid") or self:get("ssid")
  1288. end
  1289. function wifinet.bssid(self)
  1290. return self:ubus("net", "config", "bssid") or self:get("bssid")
  1291. end
  1292. function wifinet.network(self)
  1293. local net, networks = nil, { }
  1294. for net in utl.imatch(self:ubus("net", "config", "network") or self:get("network")) do
  1295. networks[#networks+1] = net
  1296. end
  1297. return networks
  1298. end
  1299. function wifinet.id(self)
  1300. return self.netid
  1301. end
  1302. function wifinet.name(self)
  1303. return self.sid
  1304. end
  1305. function wifinet.ifname(self)
  1306. local ifname = self:ubus("net", "ifname") or self.iwinfo.ifname
  1307. if not ifname or ifname:match("^wifi%d") or ifname:match("^radio%d") then
  1308. ifname = self.wdev
  1309. end
  1310. return ifname
  1311. end
  1312. function wifinet.get_device(self)
  1313. local dev = self:ubus("radio") or self:get("device")
  1314. return dev and wifidev(dev) or nil
  1315. end
  1316. function wifinet.is_up(self)
  1317. local ifc = self:get_interface()
  1318. return (ifc and ifc:is_up() or false)
  1319. end
  1320. function wifinet.active_mode(self)
  1321. local m = self.iwinfo.mode or self:ubus("net", "config", "mode") or self:get("mode") or "ap"
  1322. if m == "ap" then m = "Master"
  1323. elseif m == "sta" then m = "Client"
  1324. elseif m == "adhoc" then m = "Ad-Hoc"
  1325. elseif m == "mesh" then m = "Mesh"
  1326. elseif m == "monitor" then m = "Monitor"
  1327. end
  1328. return m
  1329. end
  1330. function wifinet.active_mode_i18n(self)
  1331. return lng.translate(self:active_mode())
  1332. end
  1333. function wifinet.active_ssid(self)
  1334. return self.iwinfo.ssid or self:ubus("net", "config", "ssid") or self:get("ssid")
  1335. end
  1336. function wifinet.active_bssid(self)
  1337. return self.iwinfo.bssid or self:ubus("net", "config", "bssid") or self:get("bssid")
  1338. end
  1339. function wifinet.active_encryption(self)
  1340. local enc = self.iwinfo and self.iwinfo.encryption
  1341. return enc and enc.description or "-"
  1342. end
  1343. function wifinet.assoclist(self)
  1344. return self.iwinfo.assoclist or { }
  1345. end
  1346. function wifinet.frequency(self)
  1347. local freq = self.iwinfo.frequency
  1348. if freq and freq > 0 then
  1349. return "%.03f" % (freq / 1000)
  1350. end
  1351. end
  1352. function wifinet.bitrate(self)
  1353. local rate = self.iwinfo.bitrate
  1354. if rate and rate > 0 then
  1355. return (rate / 1000)
  1356. end
  1357. end
  1358. function wifinet.channel(self)
  1359. return self.iwinfo.channel or self:ubus("dev", "config", "channel") or
  1360. tonumber(self:get("channel"))
  1361. end
  1362. function wifinet.signal(self)
  1363. return self.iwinfo.signal or 0
  1364. end
  1365. function wifinet.noise(self)
  1366. return self.iwinfo.noise or 0
  1367. end
  1368. function wifinet.country(self)
  1369. return self.iwinfo.country or self:ubus("dev", "config", "country") or "00"
  1370. end
  1371. function wifinet.txpower(self)
  1372. local pwr = (self.iwinfo.txpower or 0)
  1373. return pwr + self:txpower_offset()
  1374. end
  1375. function wifinet.txpower_offset(self)
  1376. return self.iwinfo.txpower_offset or 0
  1377. end
  1378. function wifinet.signal_level(self, s, n)
  1379. if self:active_bssid() ~= "00:00:00:00:00:00" then
  1380. local signal = s or self:signal()
  1381. local noise = n or self:noise()
  1382. if signal < 0 and noise < 0 then
  1383. local snr = -1 * (noise - signal)
  1384. return math.floor(snr / 5)
  1385. else
  1386. return 0
  1387. end
  1388. else
  1389. return -1
  1390. end
  1391. end
  1392. function wifinet.signal_percent(self)
  1393. local qc = self.iwinfo.quality or 0
  1394. local qm = self.iwinfo.quality_max or 0
  1395. if qc > 0 and qm > 0 then
  1396. return math.floor((100 / qm) * qc)
  1397. else
  1398. return 0
  1399. end
  1400. end
  1401. function wifinet.shortname(self)
  1402. return "%s %q" %{
  1403. lng.translate(self:active_mode()),
  1404. self:active_ssid() or self:active_bssid() or self:id()
  1405. }
  1406. end
  1407. function wifinet.get_i18n(self)
  1408. return "%s: %s %q (%s)" %{
  1409. lng.translate("Wireless Network"),
  1410. lng.translate(self:active_mode()),
  1411. self:active_ssid() or self:active_bssid() or self:id(),
  1412. self:ifname()
  1413. }
  1414. end
  1415. function wifinet.adminlink(self)
  1416. return dsp.build_url("admin", "network", "wireless", self.netid)
  1417. end
  1418. function wifinet.get_network(self)
  1419. return self:get_networks()[1]
  1420. end
  1421. function wifinet.get_networks(self)
  1422. local nets = { }
  1423. local net
  1424. for net in utl.imatch(self:ubus("net", "config", "network") or self:get("network")) do
  1425. if _uci:get("network", net) == "interface" then
  1426. nets[#nets+1] = network(net)
  1427. end
  1428. end
  1429. table.sort(nets, function(a, b) return a.sid < b.sid end)
  1430. return nets
  1431. end
  1432. function wifinet.get_interface(self)
  1433. return interface(self:ifname())
  1434. end
  1435. -- setup base protocols
  1436. _M:register_protocol("static")
  1437. _M:register_protocol("dhcp")
  1438. _M:register_protocol("none")
  1439. -- load protocol extensions
  1440. local exts = nfs.dir(utl.libpath() .. "/model/network")
  1441. if exts then
  1442. local ext
  1443. for ext in exts do
  1444. if ext:match("%.lua$") then
  1445. require("luci.model.network." .. ext:gsub("%.lua$", ""))
  1446. end
  1447. end
  1448. end