modules/admin-full: add sanity checks to interface status page
[project/luci.git] / modules / admin-full / luasrc / view / admin_status / interfaces.htm
1 <%#
2 LuCI - Lua Configuration Interface
3 Copyright 2008-2009 Steven Barth <steven@midlink.org>
4 Copyright 2008-2009 Jo-Philipp Wich <xm@leipzig.freifunk.net>
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 $Id$
13
14 -%>
15
16 <%-
17
18         require "luci.tools.webadmin"
19
20         local wba = luci.tools.webadmin
21         local uci = luci.model.uci.cursor_state()
22
23         local bridge_ifs = { }
24         local single_ifs = { }
25         local wifi_ifs   = { }
26         local devinfo    = luci.sys.net.deviceinfo()
27
28         uci:foreach("network", "interface",
29                 function(s)
30                         if s['.name'] ~= "loopback" then
31                                 if s.type == "bridge" then
32                                         bridge_ifs[#bridge_ifs+1] = s
33                                 else
34                                         single_ifs[#single_ifs+1] = s
35                                 end
36                         end
37                 end)
38
39         uci:foreach("wireless", "wifi-iface",
40                 function(s)
41                         wifi_ifs[s.network or s.device] = true
42                 end)
43
44         function is_wifi(i)
45                 return wifi_ifs[i]
46                         or i:match("^wl%d+")
47                         or i:match("^ath%d+")
48                         or i:match("^wlan%d+")
49         end
50
51         function get_ifname(s)
52                 return s.ifname and s.ifname:match("%S+")
53         end
54
55         function get_ifnames(s)
56                 local l = { }
57                 if s.ifname then
58                         for n in s.ifname:gmatch("%S+") do
59                                 l[#l+1] = n
60                         end
61                 end
62                 return l
63         end
64
65         function get_vlan(i)
66                 return i:match("^%w+%.(%d+)$")
67         end
68
69         function get_vlan_ports(i)
70                 local x = get_vlan(i)
71                 local d = i:match("(%d+)%.%d+$")
72                 local p = { }
73
74                 uci:foreach("network", "switch",
75                         function(s)
76                                 local d2 = s['.name']:match("%d+$")
77                                 if d2 == d and s["vlan"..x] then
78                                         for pt in s["vlan"..x]:gmatch("%S+") do
79                                                 p[#p+1] = pt
80                                         end
81                                 end
82                         end)
83
84                 return p
85         end
86
87         function get_switch_driver(i)
88                 local n, d = i:match("([a-z]+)(%d+)%.%d+$")
89                 local hw = luci.fs.readfile("/proc/switch/%s%s/driver" %{ n, d })
90                         or luci.fs.readfile("/proc/switch/%s/driver" % d )
91
92                 return hw and hw:match("%S+")
93         end
94
95         function get_mac(i)
96                 for l in luci.util.execi("ifconfig %q" % i) do
97                         if l:find("HWaddr ") then
98                                 return l:match("HWaddr (%S+)")
99                         end
100                 end
101                 return "00:00:00:00:00:00"
102         end
103
104         function get_aliases(s)
105                 local a = { }
106                 uci:foreach("network", "alias",
107                         function(s2)
108                                 if s2.interface == s['.name'] then
109                                         a[#a+1] = s2
110                                 end
111                         end)
112                 return a
113         end
114
115         function get_iwinfo(i)
116                 local w = { }
117                 uci:foreach("wireless", "wifi-iface",
118                         function(s)
119                                 if s.ifname == i then
120                                         w.type    = uci:get("wireless", s.device, "type")
121                                         w.channel = uci:get("wireless", s.device, "channel")
122                                         w.mode    = ( s.wds == "1" ) and s.mode .. "wds" or s.mode
123                                         w.ssid    = s.ssid
124                                         w.type    = w.type and w.type:gsub("^([a-z])", string.upper)
125                                 end
126                         end)
127                 return w
128         end
129
130         function get_iwmode(w)
131                 local m = {
132                         ap     = translate("a_s_if_iwmode_ap", "Master"),
133                         sta    = translate("a_s_if_iwmode_sta", "Client"),
134                         wds    = translate("a_s_if_iwmode_wds", "WDS"),
135                         stawds = translate("a_s_if_iwmode_stawds", "Client + WDS"),
136                         apwds  = translate("a_s_if_iwmode_apwds", "Master + WDS"),
137                         adhoc  = translate("a_s_if_iwmode_adhoc", "Ad-Hoc"),
138                         ahdemo = translate("a_s_if_iwmode_ahdemo", "Pseudo Ad-Hoc")
139                 }
140
141                 return m[w.mode] or w.mode
142         end
143
144         function get_brinfo(s)
145                 local b = { }
146                 for l in luci.util.execi("brctl show br-%s" % s['.name']) do
147                         if not l:match("STP") then
148                                 local r = luci.util.split(l, "%s+", nil, true)
149                                 if #r > 2 then
150                                         b.name    = r[1]
151                                         b.id      = r[2]
152                                         b.stp     = r[3] == "yes"
153                                         b.ifnames = { r[4] }
154                                 else
155                                         b.ifnames[#b.ifnames+1] = r[2]
156                                 end
157                         end
158                 end
159                 return b
160         end
161
162 -%>
163
164 <%+header%>
165
166 <h2><a id="content" name="content"><%:a_s_if_status Interface Status%></a></h2>
167
168 <form method="post" action="<%=REQUEST_URI%>">
169         <div class="cbi-map">
170                 <fieldset class="cbi-section">
171                         <% for _, i in ipairs(single_ifs) do
172                                 dev     = get_ifname(i)
173                                 vlan    = get_vlan(dev)
174
175                                 if devinfo and devinfo[dev] then
176                         %>
177                                 <h3><%:a_s_if_interface Interface%> <%=i['.name']%></h3>
178                                 <p style="font-size:90%;padding-left:1em">
179
180                                 <strong><%:a_s_if_device Device%>:</strong>
181                                 <%=dev%> (<%:a_s_if_mac MAC%> <%=get_mac(dev)%>)<br />
182
183                                 <strong><%:a_s_if_type Type%>:</strong>
184                                 <% if is_wifi(dev) then iw = get_iwinfo(dev) -%>
185                                         <%:a_s_if_wifidev Wireless Adapter%> (<%=iw.type%>)<br />
186                                         <% if iw then %>
187                                                 &nbsp; &#x2514; <strong><%:a_s_if_iwmode Mode%>:</strong> <%=get_iwmode(iw)%><br />
188                                                 &nbsp; &#x2514; <strong><%:a_s_if_iwssid SSID%>:</strong> <%=iw.ssid%><br />
189                                                 &nbsp; &#x2514; <strong><%:a_s_if_iwchannel Channel%>:</strong> <%=iw.channel%>
190                                         <% end %>
191                                 <% else -%>
192                                         <% if vlan then %>
193                                                 <%:a_s_if_ethswitch Ethernet Switch%> (<%=get_switch_driver(dev)%>)<br />
194                                                 &nbsp; &#x2514; <strong><%:a_s_if_vlan VLAN%>:</strong> <%=get_vlan(dev)%> (<%:a_s_if_vlanports Ports%> <%=table.concat(get_vlan_ports(dev), ", ")%>)
195                                         <% else %>
196                                                 <%:a_s_if_ethdev Ethernet Adapter%>
197                                         <% end %>
198                                 <% end -%><br />
199
200                                 <strong><%:a_s_if_transfer Transfer%></strong><br />
201                                 &nbsp; &#x2514; <strong><%:a_s_if_transfer_rx RX%>:</strong> <%=devinfo[dev][2]%> <%:a_s_if_pkts Pkts.%> (<%=wba.byte_format(tonumber(devinfo[dev][1]))%>)<br />
202                                 &nbsp; &#x2514; <strong><%:a_s_if_transfer_tx TX%>:</strong> <%=devinfo[dev][10]%> <%:a_s_if_pkts Pkts.%> (<%=wba.byte_format(tonumber(devinfo[dev][9]))%>)<br />
203
204                                 <%- if ( i.ipaddr and #i.ipaddr > 0 ) or ( i.ip6addr and #i.ip6addr > 0 ) then -%>
205                                         <strong><%:a_s_if_ipconfig IP Configuration%></strong><br />
206                                         &nbsp; &#x2514; <strong><%:a_s_if_ipconfig_primary Primary%>:</strong>
207                                         <% if i.ipaddr and #i.ipaddr > 0 then %>
208                                                 <%=i.ipaddr%>/<%=i.netmask%>
209                                                 <% if i.proto == "dhcp" then -%>
210                                                         (<%:a_s_if_ipconfig_dhcp DHCP assigned%>)
211                                                 <%- end %>
212                                         <% else %>
213                                                 <em><%:a_s_if_ipconfig_none Not configured%></em>
214                                         <% end %><br />
215
216                                         <% for i, a in ipairs(get_aliases(i)) do %>
217                                                 &nbsp; &#x2514; <strong><%:a_s_if_ipconfig_alias Alias%> #<%=i%>:</strong>
218                                                 <%=a.ipaddr%>/<%=a.netmask%> (<%:a_s_if_device Device%> <%=dev%>:<%=i%>) <br />
219                                         <% end %>
220
221                                         <% if i.ip6addr and #i.ip6addr > 0 then %>
222                                                 &nbsp; &#x2514; <strong><%:a_s_if_ipconfig_ipv6 IPv6%>:</strong> <%=i.ip6addr%><br />
223                                         <% end %>
224                                 <%- end -%>
225                                 <br /></p>
226                         <% end end %>
227
228
229                         <% for _, b in ipairs(bridge_ifs) do
230                                 br  = get_brinfo(b)
231                                 dev = br.name
232
233                                 if devinfo and devinfo[dev] then
234                         %>
235                                 <h3><%:a_s_if_bridge Bridge%> <%=br.name%></h3>
236                                 <p style="font-size:90%;padding-left:1em">
237
238                                 <strong><%:a_s_if_device Device%>:</strong>
239                                 <%=dev%> (<%:a_s_if_mac MAC%> <%=get_mac(dev)%>)<br />
240
241                                 <strong><%:a_s_if_type Type%>:</strong>
242                                 <%:a_s_if_ethbridge Ethernet Bridge%><br />
243
244                                 &nbsp; &#x2514; <strong><%:a_s_if_bridge_id ID%>:</strong> <%=br.id%><br />
245                                 &nbsp; &#x2514; <strong><%:a_s_if_bridge_stp STP%>:</strong> <%=br.stp and "enabled" or "disabled"%><br />
246
247                                 <strong><%:a_s_if_transfer Transfer%></strong><br />
248                                 &nbsp; &#x2514; <strong><%:a_s_if_transfer_rx RX%>:</strong> <%=devinfo[dev][2]%> Pkts. (<%=wba.byte_format(tonumber(devinfo[dev][1]))%>)<br />
249                                 &nbsp; &#x2514; <strong><%:a_s_if_transfer_tx TX%>:</strong> <%=devinfo[dev][10]%> Pkts. (<%=wba.byte_format(tonumber(devinfo[dev][9]))%>)<br />
250
251                                 <%- if ( b.ipaddr and #b.ipaddr > 0 ) or ( b.ip6addr and #b.ip6addr > 0 ) then -%>
252                                         <strong><%:a_s_if_ipconfig IP Configuration%></strong><br />
253                                         &nbsp; &#x2514; <strong><%:a_s_if_ipconfig_primary Primary%>:</strong>
254                                         <% if b.ipaddr and #b.ipaddr > 0 then %>
255                                                 <%=b.ipaddr%>/<%=b.netmask%>
256                                                 <% if b.proto == "dhcp" then -%>
257                                                         (<%:a_s_if_ipconfig_dhcp DHCP assigned%>)
258                                                 <%- end %>
259                                         <% else %>
260                                                 <em><%:a_s_if_ipconfig_none Not configured%></em>
261                                         <% end %><br />
262
263                                         <% for i, a in ipairs(get_aliases(b)) do %>
264                                                 &nbsp; &#x2514; <strong><%:a_s_if_ipconfig_alias Alias%> #<%=i%>:</strong>
265                                                 <%=a.ipaddr%>/<%=a.netmask%> (<%:a_s_if_device Device%> <%=dev%>:<%=i%>) <br />
266                                         <% end %>
267
268                                         <% if b.ip6addr and #b.ip6addr > 0 then %>
269                                                 &nbsp; &#x2514; <strong><%:a_s_if_ipconfig_ipv6 IPv6%>:</strong> <%=b.ip6addr%><br />
270                                         <% end %>
271                                 <%- end -%>
272
273                                 <% for n, i in ipairs(br.ifnames) do
274                                         dev     = i
275                                         vlan    = get_vlan(dev)
276                                 %>
277                                         <strong><%:a_s_if_bridge_port Bridge Port%> <%=n%></strong><br />
278
279                                         &nbsp; &#x2514; <strong><%:a_s_if_device Device%>:</strong>
280                                         <%=dev%> (<%:a_s_if_mac MAC%> <%=get_mac(dev)%>)<br />
281
282                                         &nbsp; &#x2514; <strong><%:a_s_if_type Type%>:</strong>
283                                         <% if is_wifi(dev) then iw = get_iwinfo(dev) -%>
284                                                 <%:a_s_if_wifidev Wireless Adapter%> (<%=iw.type%>)<br />
285                                                 <% if iw then %>
286                                                         &nbsp; &nbsp; &nbsp; &#x2514; <strong><%:a_s_if_iwmode Mode%>:</strong> <%=get_iwmode(iw)%><br />
287                                                         &nbsp; &nbsp; &nbsp; &#x2514; <strong><%:a_s_if_iwssid SSID%>:</strong> <%=iw.ssid%><br />
288                                                         &nbsp; &nbsp; &nbsp; &#x2514; <strong><%:a_s_if_iwchannel Channel%>:</strong> <%=iw.channel%>
289                                                 <% end %>
290                                         <% else -%>
291                                                 <% if vlan then %>
292                                                         <%:a_s_if_ethswitch Ethernet Switch%> (<%=get_switch_driver(dev)%>)<br />
293                                                         &nbsp; &nbsp; &nbsp; &#x2514; <strong><%:a_s_if_vlan VLAN%>:</strong>
294                                                         <%=get_vlan(dev)%> (<%:a_s_if_vlan_ports Ports%> <%=table.concat(get_vlan_ports(dev), ", ")%>)
295                                                 <% else %>
296                                                         <%:a_s_if_ethdev Ethernet Adapter%>
297                                                 <% end %>
298                                         <% end -%><br />
299                                 <% end %>
300                                 <br /></p>
301                         <% end end %>
302                 </fieldset>
303         </div>
304 </form>
305
306 <%+footer%>