modules/admin-full, modules/admin-core, themes/base: add port status indicators to...
[project/luci.git] / modules / admin-core / luasrc / tools / status.lua
1 --[[
2 LuCI - Lua Configuration Interface
3
4 Copyright 2011 Jo-Philipp Wich <xm@subsignal.org>
5
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
9
10         http://www.apache.org/licenses/LICENSE-2.0
11
12 ]]--
13
14 module("luci.tools.status", package.seeall)
15
16 local uci = require "luci.model.uci".cursor()
17
18 local function dhcp_leases_common(family)
19         local rv = { }
20         local nfs = require "nixio.fs"
21         local leasefile = "/var/dhcp.leases"
22
23         uci:foreach("dhcp", "dnsmasq",
24                 function(s)
25                         if s.leasefile and nfs.access(s.leasefile) then
26                                 leasefile = s.leasefile
27                                 return false
28                         end
29                 end)
30
31         local fd = io.open(leasefile, "r")
32         if fd then
33                 while true do
34                         local ln = fd:read("*l")
35                         if not ln then
36                                 break
37                         else
38                                 local ts, mac, ip, name, duid = ln:match("^(%d+) (%S+) (%S+) (%S+) (%S+)")
39                                 if ts and mac and ip and name and duid then
40                                         if family == 4 and not ip:match(":") then
41                                                 rv[#rv+1] = {
42                                                         expires  = os.difftime(tonumber(ts) or 0, os.time()),
43                                                         macaddr  = mac,
44                                                         ipaddr   = ip,
45                                                         hostname = (name ~= "*") and name
46                                                 }
47                                         elseif family == 6 and ip:match(":") then
48                                                 rv[#rv+1] = {
49                                                         expires  = os.difftime(tonumber(ts) or 0, os.time()),
50                                                         ip6addr  = ip,
51                                                         duid     = (duid ~= "*") and duid,
52                                                         hostname = (name ~= "*") and name
53                                                 }
54                                         end
55                                 end
56                         end
57                 end
58                 fd:close()
59         end
60
61         return rv
62 end
63
64 function dhcp_leases()
65         return dhcp_leases_common(4)
66 end
67
68 function dhcp6_leases()
69         if luci.sys.call("dnsmasq --version 2>/dev/null | grep -q ' DHCPv6 '") == 0 then
70                 return dhcp_leases_common(6)
71         else
72                 return nil
73         end
74 end
75
76 function wifi_networks()
77         local rv = { }
78         local ntm = require "luci.model.network".init()
79
80         local dev
81         for _, dev in ipairs(ntm:get_wifidevs()) do
82                 local rd = {
83                         up       = dev:is_up(),
84                         device   = dev:name(),
85                         name     = dev:get_i18n(),
86                         networks = { }
87                 }
88
89                 local net
90                 for _, net in ipairs(dev:get_wifinets()) do
91                         rd.networks[#rd.networks+1] = {
92                                 name       = net:shortname(),
93                                 link       = net:adminlink(),
94                                 up         = net:is_up(),
95                                 mode       = net:active_mode(),
96                                 ssid       = net:active_ssid(),
97                                 bssid      = net:active_bssid(),
98                                 encryption = net:active_encryption(),
99                                 frequency  = net:frequency(),
100                                 channel    = net:channel(),
101                                 signal     = net:signal(),
102                                 quality    = net:signal_percent(),
103                                 noise      = net:noise(),
104                                 bitrate    = net:bitrate(),
105                                 ifname     = net:ifname(),
106                                 assoclist  = net:assoclist(),
107                                 country    = net:country(),
108                                 txpower    = net:txpower(),
109                                 txpoweroff = net:txpower_offset()
110                         }
111                 end
112
113                 rv[#rv+1] = rd
114         end
115
116         return rv
117 end
118
119 function wifi_network(id)
120         local ntm = require "luci.model.network".init()
121         local net = ntm:get_wifinet(id)
122         if net then
123                 local dev = net:get_device()
124                 if dev then
125                         return {
126                                 id         = id,
127                                 name       = net:shortname(),
128                                 link       = net:adminlink(),
129                                 up         = net:is_up(),
130                                 mode       = net:active_mode(),
131                                 ssid       = net:active_ssid(),
132                                 bssid      = net:active_bssid(),
133                                 encryption = net:active_encryption(),
134                                 frequency  = net:frequency(),
135                                 channel    = net:channel(),
136                                 signal     = net:signal(),
137                                 quality    = net:signal_percent(),
138                                 noise      = net:noise(),
139                                 bitrate    = net:bitrate(),
140                                 ifname     = net:ifname(),
141                                 assoclist  = net:assoclist(),
142                                 country    = net:country(),
143                                 txpower    = net:txpower(),
144                                 txpoweroff = net:txpower_offset(),
145                                 device     = {
146                                         up     = dev:is_up(),
147                                         device = dev:name(),
148                                         name   = dev:get_i18n()
149                                 }
150                         }
151                 end
152         end
153         return { }
154 end
155
156 function switch_status(dev)
157         local ports = { }
158         local swc = io.popen("swconfig dev %q show" % dev, "r")
159         if swc then
160                 local l
161                 repeat
162                         l = swc:read("*l")
163                         if l then
164                                 local port, up = l:match("port:(%d+) link:(%w+)")
165                                 if port then
166                                         local speed  = l:match(" speed:(%d+)")
167                                         local duplex = l:match(" (%w+)-duplex")
168                                         local txflow = l:match(" (txflow)")
169                                         local rxflow = l:match(" (rxflow)")
170                                         local auto   = l:match(" (auto)")
171
172                                         ports[#ports+1] = {
173                                                 port   = tonumber(port) or 0,
174                                                 speed  = tonumber(speed) or 0,
175                                                 link   = (up == "up"),
176                                                 duplex = (duplex == "full"),
177                                                 rxflow = (not not rxflow),
178                                                 txflow = (not not txflow),
179                                                 auto   = (not not auto)
180                                         }
181                                 end
182                         end
183                 until not l
184                 swc:close()
185         end
186         return ports
187 end