4 Copyright 2009-2010 Jo-Philipp Wich <xm@subsignal.org>
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
10 http://www.apache.org/licenses/LICENSE-2.0
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
20 local type, next, pairs, ipairs, loadfile, table, tonumber, math, i18n
21 = type, next, pairs, ipairs, loadfile, table, tonumber, math, luci.i18n
23 local nxo = require "nixio"
24 local ipc = require "luci.ip"
25 local sys = require "luci.sys"
26 local utl = require "luci.util"
27 local dsp = require "luci.dispatcher"
28 local uci = require "luci.model.uci"
30 module "luci.model.network"
33 local ifs, brs, sws, uci_r, uci_s
35 function _list_del(c, s, o, r)
36 local val = uci_r:get(c, s, o)
39 if type(val) == "string" then
40 for val in val:gmatch("%S+") do
46 uci_r:set(c, s, o, table.concat(l, " "))
50 elseif type(val) == "table" then
51 for _, val in ipairs(val) do
65 function _list_add(c, s, o, a)
66 local val = uci_r:get(c, s, o) or ""
67 if type(val) == "string" then
69 for val in val:gmatch("%S+") do
75 uci_r:set(c, s, o, table.concat(l, " "))
76 elseif type(val) == "table" then
78 for _, val in ipairs(val) do
88 function _stror(s1, s2)
89 if not s1 or #s1 == 0 then
90 return s2 and #s2 > 0 and s2
96 function _get(c, s, o)
97 return uci_r:get(c, s, o)
100 function _set(c, s, o, v)
102 if type(v) == "boolean" then v = v and "1" or "0" end
103 return uci_r:set(c, s, o, v)
105 return uci_r:delete(c, s, o)
109 function _wifi_iface(x)
111 x:match("^wlan%d") or x:match("^wl%d") or x:match("^ath%d") or
112 x:match("^%w+%.network%d")
116 function _wifi_lookup(ifn)
117 -- got a radio#.network# pseudo iface, locate the corresponding section
118 local radio, ifnidx = ifn:match("^(%w+)%.network(%d+)$")
119 if radio and ifnidx then
123 ifnidx = tonumber(ifnidx)
124 uci_r:foreach("wireless", "wifi-iface",
126 if s.device == radio then
128 if num == ifnidx then
137 -- looks like wifi, try to locate the section via state vars
138 elseif _wifi_iface(ifn) then
141 uci_s:foreach("wireless", "wifi-iface",
143 if s.ifname == ifn then
153 function _iface_virtual(x)
155 x:match("^6in4-%w") or x:match("^6to4-%w") or x:match("^3g-%w") or
156 x:match("^ppp-%w") or x:match("^pppoe-%w") or x:match("^pppoa-%w") or
161 function _iface_ignore(x)
163 x:match("^wmaster%d") or x:match("^wifi%d") or x:match("^hwsim%d") or
164 x:match("^imq%d") or x:match("^mon.wlan%d") or
165 x == "sit0" or x == "lo" or _iface_virtual(x)
170 function init(cursor)
171 uci_r = cursor or uci_r or uci.cursor()
172 uci_s = uci_r:substate()
178 -- read interface information
180 for n, i in ipairs(nxo.getifaddrs()) do
181 local name = i.name:match("[^:]+")
182 local prnt = name:match("^([^%.]+)%.")
184 if _iface_virtual(name) or not _iface_ignore(name) then
185 ifs[name] = ifs[name] or {
186 idx = i.ifindex or n,
199 if i.family == "packet" then
200 ifs[name].flags = i.flags
201 ifs[name].stats = i.data
202 ifs[name].macaddr = i.addr
203 elseif i.family == "inet" then
204 ifs[name].ipaddrs[#ifs[name].ipaddrs+1] = ipc.IPv4(i.addr, i.netmask)
205 elseif i.family == "inet6" then
206 ifs[name].ip6addrs[#ifs[name].ip6addrs+1] = ipc.IPv6(i.addr, i.netmask)
211 -- read bridge informaton
213 for l in utl.execi("brctl show") do
214 if not l:match("STP") then
215 local r = utl.split(l, "%s+", nil, true)
221 ifnames = { ifs[r[4]] }
224 b.ifnames[1].bridge = b
228 b.ifnames[#b.ifnames+1] = ifs[r[2]]
229 b.ifnames[#b.ifnames].bridge = b
237 function save(self, ...)
242 function commit(self, ...)
247 function has_ipv6(self)
248 return nfs.access("/proc/net/ipv6_route")
251 function add_network(self, n, options)
252 local oldnet = self:get_network(n)
253 if n and #n > 0 and n:match("^[a-zA-Z0-9_]+$") and not oldnet then
254 if uci_r:section("network", "interface", n, options) then
257 elseif oldnet and oldnet:is_empty() then
260 for k, v in pairs(options) do
268 function get_network(self, n)
269 if n and uci_r:get("network", n) == "interface" then
274 function get_networks(self)
278 uci_r:foreach("network", "interface",
280 nls[s['.name']] = network(s['.name'])
284 for n in utl.kspairs(nls) do
285 nets[#nets+1] = nls[n]
291 function del_network(self, n)
292 local r = uci_r:delete("network", n)
294 uci_r:delete_all("network", "alias",
295 function(s) return (s.interface == n) end)
297 uci_r:delete_all("network", "route",
298 function(s) return (s.interface == n) end)
300 uci_r:delete_all("network", "route6",
301 function(s) return (s.interface == n) end)
303 uci_r:foreach("wireless", "wifi-iface",
305 if s.network == n then
306 uci_r:delete("wireless", s['.name'], "network")
313 function rename_network(self, old, new)
315 if new and #new > 0 and new:match("^[a-zA-Z0-9_]+$") and not self:get_network(new) then
316 r = uci_r:section("network", "interface", new, uci_r:get_all("network", old))
319 uci_r:foreach("network", "alias",
321 if s.interface == old then
322 uci_r:set("network", s['.name'], "interface", new)
326 uci_r:foreach("network", "route",
328 if s.interface == old then
329 uci_r:set("network", s['.name'], "interface", new)
333 uci_r:foreach("network", "route6",
335 if s.interface == old then
336 uci_r:set("network", s['.name'], "interface", new)
340 uci_r:foreach("wireless", "wifi-iface",
342 if s.network == old then
343 uci_r:set("wireless", s['.name'], "network", new)
347 uci_r:delete("network", old)
353 function get_interface(self, i)
354 if ifs[i] or _wifi_iface(i) then
359 uci_r:foreach("wireless", "wifi-iface",
362 num[s.device] = num[s.device] and num[s.device] + 1 or 1
363 if s['.name'] == i then
365 "%s.network%d" %{s.device, num[s.device] })
374 function get_interfaces(self)
380 -- find normal interfaces
381 uci_r:foreach("network", "interface",
383 for iface in utl.imatch(s.ifname) do
384 if not _iface_ignore(iface) and not _wifi_iface(iface) then
386 nfs[iface] = interface(iface)
391 for iface in utl.kspairs(ifs) do
392 if not (seen[iface] or _iface_ignore(iface) or _wifi_iface(iface)) then
393 nfs[iface] = interface(iface)
397 -- find vlan interfaces
398 uci_r:foreach("network", "switch_vlan",
400 local base = s.device or "-"
401 if not base:match("^eth%d") then
405 local vid = tonumber(s.vid or s.vlan)
406 if vid ~= nil and vid >= 0 and vid <= 4095 then
407 local iface = "%s.%d" %{ base, vid }
408 if not seen[iface] then
410 nfs[iface] = interface(iface)
415 for iface in utl.kspairs(nfs) do
416 ifaces[#ifaces+1] = nfs[iface]
419 -- find wifi interfaces
422 uci_r:foreach("wireless", "wifi-iface",
425 num[s.device] = num[s.device] and num[s.device] + 1 or 1
426 local i = "%s.network%d" %{ s.device, num[s.device] }
427 wfs[i] = interface(i)
431 for iface in utl.kspairs(wfs) do
432 ifaces[#ifaces+1] = wfs[iface]
438 function ignore_interface(self, x)
439 return _iface_ignore(x)
442 function get_wifidev(self, dev)
443 if uci_r:get("wireless", dev) == "wifi-device" then
448 function get_wifidevs(self)
452 uci_r:foreach("wireless", "wifi-device",
453 function(s) wfd[#wfd+1] = s['.name'] end)
456 for _, dev in utl.vspairs(wfd) do
457 devs[#devs+1] = wifidev(dev)
463 function get_wifinet(self, net)
464 local wnet = _wifi_lookup(net)
470 function add_wifinet(self, net, options)
471 if type(options) == "table" and options.device and
472 uci_r:get("wireless", options.device) == "wifi-device"
474 local wnet = uci_r:section("wireless", "wifi-iface", nil, options)
479 function del_wifinet(self, net)
480 local wnet = _wifi_lookup(net)
482 uci_r:delete("wireless", wnet)
489 network = utl.class()
491 function network.__init__(self, name)
495 function network._get(self, opt)
496 local v = uci_r:get("network", self.sid, opt)
497 if type(v) == "table" then
498 return table.concat(v, " ")
503 function network._ip(self, opt, family, list)
504 local ip = uci_s:get("network", self.sid, opt)
505 local fc = (family == 6) and ipc.IPv6 or ipc.IPv4
509 for ip in utl.imatch(ip) do
511 if ip then l[#l+1] = ip:string() end
516 return ip and ip:string()
521 function network.get(self, opt)
522 return _get("network", self.sid, opt)
525 function network.set(self, opt, val)
526 return _set("network", self.sid, opt, val)
529 function network.ifname(self)
530 local p = self:proto()
531 if self:is_bridge() then
532 return "br-" .. self.sid
533 elseif self:proto() == "relay" then
534 return uci_s:get("network", self.sid, "up") == "1" and "lo" or nil
535 elseif self:is_virtual() then
536 return p .. "-" .. self.sid
539 local dev = uci_r:get("network", self.sid, "ifname") or
540 uci_s:get("network", self.sid, "ifname")
542 dev = (type(dev) == "table") and dev[1] or dev
543 dev = (dev ~= nil) and dev:match("%S+")
546 uci_r:foreach("wireless", "wifi-iface",
549 num[s.device] = num[s.device]
550 and num[s.device] + 1 or 1
552 if s.network == self.sid then
553 dev = "%s.network%d" %{ s.device, num[s.device] }
564 function network.device(self)
565 local dev = uci_r:get("network", self.sid, "device") or
566 uci_s:get("network", self.sid, "device")
568 dev = (type(dev) == "table") and dev[1] or dev
570 if not dev or dev:match("[^%w%-%.%s]") then
571 dev = uci_r:get("network", self.sid, "ifname") or
572 uci_s:get("network", self.sid, "ifname")
574 dev = (type(dev) == "table") and dev[1] or dev
577 for dev in utl.imatch(dev) do
582 function network.proto(self)
583 return self:_get("proto") or "none"
586 function network.type(self)
587 return self:_get("type")
590 function network.name(self)
594 function network.uptime(self)
595 local cnt = tonumber(uci_s:get("network", self.sid, "connect_time"))
597 return nxo.sysinfo().uptime - cnt
603 function network.expires(self)
604 local a = tonumber(uci_s:get("network", self.sid, "lease_acquired"))
605 local l = tonumber(uci_s:get("network", self.sid, "lease_lifetime"))
607 l = l - (nxo.sysinfo().uptime - a)
608 return l > 0 and l or 0
613 function network.metric(self)
614 return tonumber(uci_s:get("network", self.sid, "metric")) or 0
617 function network.ipaddr(self)
618 return self:_ip("ipaddr", 4)
621 function network.netmask(self)
622 return self:_ip("netmask", 4)
625 function network.gwaddr(self)
626 return self:_ip("gateway", 4)
629 function network.dnsaddrs(self)
630 return self:_ip("dns", 4, true)
633 function network.ip6addr(self)
634 local ip6 = self:_ip("ip6addr", 6)
636 local ifc = ifs[self:ifname()]
637 if ifc and ifc.ip6addrs then
639 for _, a in ipairs(ifc.ip6addrs) do
640 if not a:is6linklocal() then
650 function network.gw6addr(self)
651 local ip6 = self:_ip("ip6gw", 6)
653 local dr6 = sys.net.defaultroute6()
654 if dr6 and dr6.device == self:ifname() then
655 return dr6.nexthop:string()
661 function network.dns6addrs(self)
662 return self:_ip("dns", 6, true)
665 function network.is_bridge(self)
666 return (self:type() == "bridge")
669 function network.is_virtual(self)
670 local p = self:proto()
672 p == "3g" or p == "6in4" or p == "6to4" or p == "ppp" or
673 p == "pppoe" or p == "pppoa" or p == "relay"
677 function network.is_empty(self)
678 if self:is_virtual() then
683 if (self:_get("ifname") or ""):match("%S+") then
687 uci_r:foreach("wireless", "wifi-iface",
689 if s.network == self.sid then
699 function network.add_interface(self, ifname)
700 if not self:is_virtual() then
701 if type(ifname) ~= "string" then
702 ifname = ifname:name()
704 ifname = ifname:match("[^%s:]+")
707 -- remove the interface from all ifaces
708 uci_r:foreach("network", "interface",
710 _list_del("network", s['.name'], "ifname", ifname)
713 -- if its a wifi interface, change its network option
714 local wif = _wifi_lookup(ifname)
716 uci_r:set("wireless", wif, "network", self.sid)
718 -- add iface to our iface list
720 _list_add("network", self.sid, "ifname", ifname)
725 function network.del_interface(self, ifname)
726 if not self:is_virtual() then
727 if utl.instanceof(ifname, interface) then
728 ifname = ifname:name()
730 ifname = ifname:match("[^%s:]+")
733 -- if its a wireless interface, clear its network option
734 local wif = _wifi_lookup(ifname)
735 if wif then uci_r:delete("wireless", wif, "network") end
737 -- remove the interface
738 _list_del("network", self.sid, "ifname", ifname)
742 function network.get_interfaces(self)
746 if self:is_virtual() then
747 ifn = self:proto() .. "-" .. self.sid
748 ifaces = { interface(ifn) }
751 for ifn in utl.imatch(self:get("ifname")) do
752 ifn = ifn:match("[^:]+")
753 nfs[ifn] = interface(ifn)
756 for ifn in utl.kspairs(nfs) do
757 ifaces[#ifaces+1] = nfs[ifn]
762 uci_r:foreach("wireless", "wifi-iface",
765 num[s.device] = num[s.device] and num[s.device] + 1 or 1
766 if s.network == self.sid then
767 ifn = "%s.network%d" %{ s.device, num[s.device] }
768 wfs[ifn] = interface(ifn)
773 for ifn in utl.kspairs(wfs) do
774 ifaces[#ifaces+1] = wfs[ifn]
781 function network.contains_interface(self, ifname)
782 if type(ifname) ~= "string" then
783 ifname = ifname:name()
785 ifname = ifname:match("[^%s:]+")
789 if self:is_virtual() then
790 ifn = self:proto() .. "-" .. self.sid
793 for ifn in utl.imatch(self:get("ifname")) do
794 ifn = ifn:match("[^:]+")
795 if ifn == ifname then
800 local wif = _wifi_lookup(ifname)
802 return (uci_r:get("wireless", wif, "network") == self.sid)
809 function network.adminlink(self)
810 return dsp.build_url("admin", "network", "network", self.sid)
814 interface = utl.class()
815 function interface.__init__(self, ifname)
816 local wif = _wifi_lookup(ifname)
817 if wif then self.wif = wifinet(wif) end
819 self.ifname = self.ifname or ifname
820 self.dev = ifs[self.ifname]
823 function interface.name(self)
824 return self.wif and self.wif:ifname() or self.ifname
827 function interface.mac(self)
828 return self.dev and self.dev.macaddr or "00:00:00:00:00:00"
831 function interface.ipaddrs(self)
832 return self.dev and self.dev.ipaddrs or { }
835 function interface.ip6addrs(self)
836 return self.dev and self.dev.ip6addrs or { }
839 function interface.type(self)
840 if self.wif or _wifi_iface(self.ifname) then
842 elseif brs[self.ifname] then
844 elseif self.ifname:match("%.") then
846 elseif sws[self.ifname] then
853 function interface.shortname(self)
856 self.wif:active_mode(),
857 self.wif:active_ssid() or self.wif:active_bssid()
864 function interface.get_i18n(self)
866 return "%s: %s %q" %{
867 i18n.translate("Wireless Network"),
868 self.wif:active_mode(),
869 self.wif:active_ssid() or self.wif:active_bssid()
872 return "%s: %q" %{ self:get_type_i18n(), self:name() }
876 function interface.get_type_i18n(self)
877 local x = self:type()
879 return i18n.translate("Wireless Adapter")
880 elseif x == "bridge" then
881 return i18n.translate("Bridge")
882 elseif x == "switch" then
883 return i18n.translate("Ethernet Switch")
884 elseif x == "vlan" then
885 return i18n.translate("VLAN Interface")
887 return i18n.translate("Ethernet Adapter")
891 function interface.adminlink(self)
893 return self.wif:adminlink()
897 function interface.ports(self)
901 for _, iface in ipairs(self.br.ifnames) do
902 ifaces[#ifaces+1] = interface(iface.name)
908 function interface.bridge_id(self)
916 function interface.bridge_stp(self)
924 function interface.is_up(self)
926 return self.wif:is_up()
928 return self.dev and self.dev.flags and self.dev.flags.up or false
932 function interface.is_bridge(self)
933 return (self:type() == "bridge")
936 function interface.is_bridgeport(self)
937 return self.dev and self.dev.bridge and true or false
940 function interface.tx_bytes(self)
941 return self.dev and self.dev.stats
942 and self.dev.stats.tx_bytes or 0
945 function interface.rx_bytes(self)
946 return self.dev and self.dev.stats
947 and self.dev.stats.rx_bytes or 0
950 function interface.tx_packets(self)
951 return self.dev and self.dev.stats
952 and self.dev.stats.tx_packets or 0
955 function interface.rx_packets(self)
956 return self.dev and self.dev.stats
957 and self.dev.stats.rx_packets or 0
960 function interface.get_network(self)
961 if self.dev and self.dev.network then
962 self.network = _M:get_network(self.dev.network)
965 if not self.network then
967 for _, net in ipairs(_M:get_networks()) do
968 if net:contains_interface(self.ifname) or
969 net:ifname() == self.ifname
980 function interface.get_wifinet(self)
985 wifidev = utl.class()
986 function wifidev.__init__(self, dev)
988 self.iwinfo = dev and sys.wifi.getiwinfo(dev) or { }
991 function wifidev.get(self, opt)
992 return _get("wireless", self.sid, opt)
995 function wifidev.set(self, opt, val)
996 return _set("wireless", self.sid, opt, val)
999 function wifidev.name(self)
1003 function wifidev.hwmodes(self)
1004 local l = self.iwinfo.hwmodelist
1005 if l and next(l) then
1008 return { b = true, g = true }
1012 function wifidev.get_i18n(self)
1014 if self.iwinfo.type == "wl" then
1016 elseif self.iwinfo.type == "madwifi" then
1021 local l = self:hwmodes()
1022 if l.a then m = m .. "a" end
1023 if l.b then m = m .. "b" end
1024 if l.g then m = m .. "g" end
1025 if l.n then m = m .. "n" end
1027 return "%s 802.11%s Wireless Controller (%s)" %{ t, m, self:name() }
1030 function wifidev.is_up(self)
1033 uci_s:foreach("wireless", "wifi-iface",
1035 if s.device == self.sid then
1046 function wifidev.get_wifinet(self, net)
1047 if uci_r:get("wireless", net) == "wifi-iface" then
1050 local wnet = _wifi_lookup(net)
1052 return wifinet(wnet)
1057 function wifidev.get_wifinets(self)
1060 uci_r:foreach("wireless", "wifi-iface",
1062 if s.device == self.sid then
1063 nets[#nets+1] = wifinet(s['.name'])
1070 function wifidev.add_wifinet(self, options)
1071 options = options or { }
1072 options.device = self.sid
1074 local wnet = uci_r:section("wireless", "wifi-iface", nil, options)
1076 return wifinet(wnet, options)
1080 function wifidev.del_wifinet(self, net)
1081 if utl.instanceof(net, wifinet) then
1083 elseif uci_r:get("wireless", net) ~= "wifi-iface" then
1084 net = _wifi_lookup(net)
1087 if net and uci_r:get("wireless", net, "device") == self.sid then
1088 uci_r:delete("wireless", net)
1096 wifinet = utl.class()
1097 function wifinet.__init__(self, net, data)
1102 uci_r:foreach("wireless", "wifi-iface",
1105 num[s.device] = num[s.device] and num[s.device] + 1 or 1
1106 if s['.name'] == self.sid then
1107 netid = "%s.network%d" %{ s.device, num[s.device] }
1113 local dev = uci_s:get("wireless", self.sid, "ifname") or netid
1117 self.iwinfo = dev and sys.wifi.getiwinfo(dev) or { }
1118 self.iwdata = data or uci_s:get_all("wireless", self.sid) or
1119 uci_r:get_all("wireless", self.sid) or { }
1122 function wifinet.get(self, opt)
1123 return _get("wireless", self.sid, opt)
1126 function wifinet.set(self, opt, val)
1127 return _set("wireless", self.sid, opt, val)
1130 function wifinet.mode(self)
1131 return uci_s:get("wireless", self.sid, "mode") or "ap"
1134 function wifinet.ssid(self)
1135 return uci_s:get("wireless", self.sid, "ssid")
1138 function wifinet.bssid(self)
1139 return uci_s:get("wireless", self.sid, "bssid")
1142 function wifinet.network(self)
1143 return uci_s:get("wifinet", self.sid, "network")
1146 function wifinet.id(self)
1150 function wifinet.name(self)
1154 function wifinet.ifname(self)
1155 local ifname = self.iwinfo.ifname
1156 if not ifname or ifname:match("^wifi%d") or ifname:match("^radio%d") then
1162 function wifinet.get_device(self)
1163 if self.iwdata.device then
1164 return wifidev(self.iwdata.device)
1168 function wifinet.is_up(self)
1169 return (self.iwdata.up == "1")
1172 function wifinet.active_mode(self)
1173 local m = _stror(self.iwinfo.mode, self.iwdata.mode) or "ap"
1175 if m == "ap" then m = "Master"
1176 elseif m == "sta" then m = "Client"
1177 elseif m == "adhoc" then m = "Ad-Hoc"
1178 elseif m == "mesh" then m = "Mesh"
1179 elseif m == "monitor" then m = "Monitor"
1185 function wifinet.active_mode_i18n(self)
1186 return i18n.translate(self:active_mode())
1189 function wifinet.active_ssid(self)
1190 return _stror(self.iwinfo.ssid, self.iwdata.ssid)
1193 function wifinet.active_bssid(self)
1194 return _stror(self.iwinfo.bssid, self.iwdata.bssid) or "00:00:00:00:00:00"
1197 function wifinet.active_encryption(self)
1198 local enc = self.iwinfo and self.iwinfo.encryption
1199 return enc and enc.description or "-"
1202 function wifinet.assoclist(self)
1203 return self.iwinfo.assoclist or { }
1206 function wifinet.frequency(self)
1207 local freq = self.iwinfo.frequency
1208 if freq and freq > 0 then
1209 return "%.03f" % (freq / 1000)
1213 function wifinet.bitrate(self)
1214 local rate = self.iwinfo.bitrate
1215 if rate and rate > 0 then
1216 return (rate / 1000)
1220 function wifinet.channel(self)
1221 return self.iwinfo.channel or
1222 tonumber(uci_s:get("wireless", self.iwdata.device, "channel"))
1225 function wifinet.signal(self)
1226 return self.iwinfo.signal or 0
1229 function wifinet.noise(self)
1230 return self.iwinfo.noise or 0
1233 function wifinet.country(self)
1234 return self.iwinfo.country or "00"
1237 function wifinet.txpower(self)
1238 return self.iwinfo.txpower or 0
1241 function wifinet.signal_level(self, s, n)
1242 if self:active_bssid() ~= "00:00:00:00:00:00" then
1243 local signal = s or self:signal()
1244 local noise = n or self:noise()
1246 if signal < 0 and noise < 0 then
1247 local snr = -1 * (noise - signal)
1248 return math.floor(snr / 5)
1257 function wifinet.signal_percent(self)
1258 local qc = self.iwinfo.quality or 0
1259 local qm = self.iwinfo.quality_max or 0
1261 if qc > 0 and qm > 0 then
1262 return math.floor((100 / qm) * qc)
1268 function wifinet.shortname(self)
1270 i18n.translate(self:active_mode()),
1271 self:active_ssid() or self:active_bssid()
1275 function wifinet.get_i18n(self)
1276 return "%s: %s %q (%s)" %{
1277 i18n.translate("Wireless Network"),
1278 i18n.translate(self:active_mode()),
1279 self:active_ssid() or self:active_bssid(),
1284 function wifinet.adminlink(self)
1285 return dsp.build_url("admin", "network", "wireless", self.netid)
1288 function wifinet.get_network(self)
1289 if uci_r:get("network", self.iwdata.network) == "interface" then
1290 return network(self.iwdata.network)
1294 function wifinet.get_interface(self)
1295 return interface(self:ifname())