index.htm 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706
  1. <%#
  2. Copyright 2008 Steven Barth <steven@midlink.org>
  3. Copyright 2008-2011 Jo-Philipp Wich <jow@openwrt.org>
  4. Licensed to the public under the Apache License 2.0.
  5. -%>
  6. <%
  7. local fs = require "nixio.fs"
  8. local util = require "luci.util"
  9. local stat = require "luci.tools.status"
  10. local ver = require "luci.version"
  11. local has_ipv6 = fs.access("/proc/net/ipv6_route")
  12. local has_dhcp = fs.access("/etc/config/dhcp")
  13. local has_wifi = ((fs.stat("/etc/config/wireless", "size") or 0) > 0)
  14. local sysinfo = luci.util.ubus("system", "info") or { }
  15. local boardinfo = luci.util.ubus("system", "board") or { }
  16. local unameinfo = nixio.uname() or { }
  17. local meminfo = sysinfo.memory or {
  18. total = 0,
  19. free = 0,
  20. buffered = 0,
  21. shared = 0
  22. }
  23. local swapinfo = sysinfo.swap or {
  24. total = 0,
  25. free = 0
  26. }
  27. local has_dsl = fs.access("/etc/init.d/dsl_control")
  28. if luci.http.formvalue("status") == "1" then
  29. local ntm = require "luci.model.network".init()
  30. local wan = ntm:get_wannet()
  31. local wan6 = ntm:get_wan6net()
  32. local conn_count = tonumber((
  33. luci.sys.exec("wc -l /proc/net/nf_conntrack") or
  34. luci.sys.exec("wc -l /proc/net/ip_conntrack") or
  35. ""):match("%d+")) or 0
  36. local conn_max = tonumber((
  37. luci.sys.exec("sysctl net.nf_conntrack_max") or
  38. luci.sys.exec("sysctl net.ipv4.netfilter.ip_conntrack_max") or
  39. ""):match("%d+")) or 4096
  40. local rv = {
  41. uptime = sysinfo.uptime or 0,
  42. localtime = os.date(),
  43. loadavg = sysinfo.load or { 0, 0, 0 },
  44. memory = meminfo,
  45. swap = swapinfo,
  46. connmax = conn_max,
  47. conncount = conn_count,
  48. leases = stat.dhcp_leases(),
  49. leases6 = stat.dhcp6_leases(),
  50. wifinets = stat.wifi_networks()
  51. }
  52. if wan then
  53. rv.wan = {
  54. ipaddr = wan:ipaddr(),
  55. gwaddr = wan:gwaddr(),
  56. netmask = wan:netmask(),
  57. dns = wan:dnsaddrs(),
  58. expires = wan:expires(),
  59. uptime = wan:uptime(),
  60. proto = wan:proto(),
  61. ifname = wan:ifname(),
  62. link = wan:adminlink()
  63. }
  64. end
  65. if wan6 then
  66. rv.wan6 = {
  67. ip6addr = wan6:ip6addr(),
  68. gw6addr = wan6:gw6addr(),
  69. dns = wan6:dns6addrs(),
  70. uptime = wan6:uptime(),
  71. ifname = wan6:ifname(),
  72. link = wan6:adminlink()
  73. }
  74. end
  75. if has_dsl then
  76. local dsl_stat = luci.sys.exec("/etc/init.d/dsl_control lucistat")
  77. local dsl_func = loadstring(dsl_stat)
  78. if dsl_func then
  79. rv.dsl = dsl_func()
  80. end
  81. end
  82. luci.http.prepare_content("application/json")
  83. luci.http.write_json(rv)
  84. return
  85. end
  86. -%>
  87. <%+header%>
  88. <script type="text/javascript" src="<%=resource%>/cbi.js"></script>
  89. <script type="text/javascript">//<![CDATA[
  90. function progressbar(v, m)
  91. {
  92. var vn = parseInt(v) || 0;
  93. var mn = parseInt(m) || 100;
  94. var pc = Math.floor((100 / mn) * vn);
  95. return String.format(
  96. '<div style="width:200px; position:relative; border:1px solid #999999">' +
  97. '<div style="background-color:#CCCCCC; width:%d%%; height:15px">' +
  98. '<div style="position:absolute; left:0; top:0; text-align:center; width:100%%; color:#000000">' +
  99. '<small>%s / %s (%d%%)</small>' +
  100. '</div>' +
  101. '</div>' +
  102. '</div>', pc, v, m, pc
  103. );
  104. }
  105. var wifidevs = <%=luci.http.write_json(netdevs)%>;
  106. var arptable = <%=luci.http.write_json(arpcache)%>;
  107. XHR.poll(5, '<%=REQUEST_URI%>', { status: 1 },
  108. function(x, info)
  109. {
  110. var si = document.getElementById('wan4_i');
  111. var ss = document.getElementById('wan4_s');
  112. var ifc = info.wan;
  113. if (ifc && ifc.ifname && ifc.proto != 'none')
  114. {
  115. var s = String.format(
  116. '<strong><%:Type%>: </strong>%s<br />' +
  117. '<strong><%:Address%>: </strong>%s<br />' +
  118. '<strong><%:Netmask%>: </strong>%s<br />' +
  119. '<strong><%:Gateway%>: </strong>%s<br />',
  120. ifc.proto,
  121. (ifc.ipaddr) ? ifc.ipaddr : '0.0.0.0',
  122. (ifc.netmask && ifc.netmask != ifc.ipaddr) ? ifc.netmask : '255.255.255.255',
  123. (ifc.gwaddr) ? ifc.gwaddr : '0.0.0.0'
  124. );
  125. for (var i = 0; i < ifc.dns.length; i++)
  126. {
  127. s += String.format(
  128. '<strong><%:DNS%> %d: </strong>%s<br />',
  129. i + 1, ifc.dns[i]
  130. );
  131. }
  132. if (ifc.expires > -1)
  133. {
  134. s += String.format(
  135. '<strong><%:Expires%>: </strong>%t<br />',
  136. ifc.expires
  137. );
  138. }
  139. if (ifc.uptime > 0)
  140. {
  141. s += String.format(
  142. '<strong><%:Connected%>: </strong>%t<br />',
  143. ifc.uptime
  144. );
  145. }
  146. ss.innerHTML = String.format('<small>%s</small>', s);
  147. si.innerHTML = String.format(
  148. '<img src="<%=resource%>/icons/ethernet.png" />' +
  149. '<br /><small><a href="%s">%s</a></small>',
  150. ifc.link, ifc.ifname
  151. );
  152. }
  153. else
  154. {
  155. si.innerHTML = '<img src="<%=resource%>/icons/ethernet_disabled.png" /><br /><small>?</small>';
  156. ss.innerHTML = '<em><%:Not connected%></em>';
  157. }
  158. <% if has_ipv6 then %>
  159. var si6 = document.getElementById('wan6_i');
  160. var ss6 = document.getElementById('wan6_s');
  161. var ifc6 = info.wan6;
  162. if (ifc6 && ifc6.ifname && ifc6.proto != 'none')
  163. {
  164. var s = String.format(
  165. '<strong><%:Address%>: </strong>%s<br />' +
  166. '<strong><%:Gateway%>: </strong>%s<br />',
  167. (ifc6.ip6addr) ? ifc6.ip6addr : '::',
  168. (ifc6.gw6addr) ? ifc6.gw6addr : '::'
  169. );
  170. for (var i = 0; i < ifc6.dns.length; i++)
  171. {
  172. s += String.format(
  173. '<strong><%:DNS%> %d: </strong>%s<br />',
  174. i + 1, ifc6.dns[i]
  175. );
  176. }
  177. if (ifc6.uptime > 0)
  178. {
  179. s += String.format(
  180. '<strong><%:Connected%>: </strong>%t<br />',
  181. ifc6.uptime
  182. );
  183. }
  184. ss6.innerHTML = String.format('<small>%s</small>', s);
  185. si6.innerHTML = String.format(
  186. '<img src="<%=resource%>/icons/ethernet.png" />' +
  187. '<br /><small><a href="%s">%s</a></small>',
  188. ifc6.link, ifc6.ifname
  189. );
  190. }
  191. else
  192. {
  193. si6.innerHTML = '<img src="<%=resource%>/icons/ethernet_disabled.png" /><br /><small>?</small>';
  194. ss6.innerHTML = '<em><%:Not connected%></em>';
  195. }
  196. <% end %>
  197. <% if has_dsl then %>
  198. var dsl_i = document.getElementById('dsl_i');
  199. var dsl_s = document.getElementById('dsl_s');
  200. var s = String.format(
  201. '<strong><%:Status%>: </strong>%s<br />' +
  202. '<strong><%:Line State%>: </strong>%s [0x%x]<br />' +
  203. '<strong><%:Line Speed%>: </strong>%s/s / %s/s<br />' +
  204. '<strong><%:Line Attenuation%>: </strong>%s dB / %s dB<br />' +
  205. '<strong><%:Noise Margin%>: </strong>%s dB / %s dB<br />',
  206. info.dsl.line_state, info.dsl.line_state_detail,
  207. info.dsl.line_state_num,
  208. info.dsl.data_rate_down_s, info.dsl.data_rate_up_s,
  209. info.dsl.line_attenuation_down, info.dsl.line_attenuation_up,
  210. info.dsl.noise_margin_down, info.dsl.noise_margin_up
  211. );
  212. dsl_s.innerHTML = String.format('<small>%s</small>', s);
  213. dsl_i.innerHTML = String.format(
  214. '<img src="<%=resource%>/icons/ethernet.png" />' +
  215. '<br /><small>ADSL</small>'
  216. );
  217. <% end %>
  218. <% if has_dhcp then %>
  219. var ls = document.getElementById('lease_status_table');
  220. if (ls)
  221. {
  222. /* clear all rows */
  223. while( ls.rows.length > 1 )
  224. ls.rows[0].parentNode.deleteRow(1);
  225. for( var i = 0; i < info.leases.length; i++ )
  226. {
  227. var timestr;
  228. if (info.leases[i].expires <= 0)
  229. timestr = '<em><%:expired%></em>';
  230. else
  231. timestr = String.format('%t', info.leases[i].expires);
  232. var tr = ls.rows[0].parentNode.insertRow(-1);
  233. tr.className = 'cbi-section-table-row cbi-rowstyle-' + ((i % 2) + 1);
  234. tr.insertCell(-1).innerHTML = info.leases[i].hostname ? info.leases[i].hostname : '?';
  235. tr.insertCell(-1).innerHTML = info.leases[i].ipaddr;
  236. tr.insertCell(-1).innerHTML = info.leases[i].macaddr;
  237. tr.insertCell(-1).innerHTML = timestr;
  238. }
  239. if( ls.rows.length == 1 )
  240. {
  241. var tr = ls.rows[0].parentNode.insertRow(-1);
  242. tr.className = 'cbi-section-table-row';
  243. var td = tr.insertCell(-1);
  244. td.colSpan = 4;
  245. td.innerHTML = '<em><br /><%:There are no active leases.%></em>';
  246. }
  247. }
  248. var ls6 = document.getElementById('lease6_status_table');
  249. if (ls6 && info.leases6)
  250. {
  251. ls6.parentNode.style.display = 'block';
  252. /* clear all rows */
  253. while( ls6.rows.length > 1 )
  254. ls6.rows[0].parentNode.deleteRow(1);
  255. for( var i = 0; i < info.leases6.length; i++ )
  256. {
  257. var timestr;
  258. if (info.leases6[i].expires <= 0)
  259. timestr = '<em><%:expired%></em>';
  260. else
  261. timestr = String.format('%t', info.leases6[i].expires);
  262. var tr = ls6.rows[0].parentNode.insertRow(-1);
  263. tr.className = 'cbi-section-table-row cbi-rowstyle-' + ((i % 2) + 1);
  264. tr.insertCell(-1).innerHTML = info.leases6[i].hostname ? info.leases6[i].hostname : '?';
  265. tr.insertCell(-1).innerHTML = info.leases6[i].ip6addr;
  266. tr.insertCell(-1).innerHTML = info.leases6[i].duid;
  267. tr.insertCell(-1).innerHTML = timestr;
  268. }
  269. if( ls6.rows.length == 1 )
  270. {
  271. var tr = ls6.rows[0].parentNode.insertRow(-1);
  272. tr.className = 'cbi-section-table-row';
  273. var td = tr.insertCell(-1);
  274. td.colSpan = 4;
  275. td.innerHTML = '<em><br /><%:There are no active leases.%></em>';
  276. }
  277. }
  278. <% end %>
  279. <% if has_wifi then %>
  280. var assoclist = [ ];
  281. var ws = document.getElementById('wifi_status_table');
  282. if (ws)
  283. {
  284. var wsbody = ws.rows[0].parentNode;
  285. while (ws.rows.length > 0)
  286. wsbody.deleteRow(0);
  287. for (var didx = 0; didx < info.wifinets.length; didx++)
  288. {
  289. var dev = info.wifinets[didx];
  290. var tr = wsbody.insertRow(-1);
  291. var td;
  292. td = tr.insertCell(-1);
  293. td.width = "33%";
  294. td.innerHTML = dev.name;
  295. td.style.verticalAlign = "top";
  296. td = tr.insertCell(-1);
  297. var s = '';
  298. for (var nidx = 0; nidx < dev.networks.length; nidx++)
  299. {
  300. var net = dev.networks[nidx];
  301. var is_assoc = (net.bssid != '00:00:00:00:00:00' && net.channel && !net.disabled);
  302. var icon;
  303. if (!is_assoc)
  304. icon = "<%=resource%>/icons/signal-none.png";
  305. else if (net.quality == 0)
  306. icon = "<%=resource%>/icons/signal-0.png";
  307. else if (net.quality < 25)
  308. icon = "<%=resource%>/icons/signal-0-25.png";
  309. else if (net.quality < 50)
  310. icon = "<%=resource%>/icons/signal-25-50.png";
  311. else if (net.quality < 75)
  312. icon = "<%=resource%>/icons/signal-50-75.png";
  313. else
  314. icon = "<%=resource%>/icons/signal-75-100.png";
  315. s += String.format(
  316. '<table><tr><td style="text-align:center; width:32px; padding:3px">' +
  317. '<img src="%s" title="<%:Signal%>: %d dBm / <%:Noise%>: %d dBm" />' +
  318. '<br /><small>%d%%</small>' +
  319. '</td><td style="text-align:left; padding:3px"><small>' +
  320. '<strong><%:SSID%>:</strong> <a href="%s">%h</a><br />' +
  321. '<strong><%:Mode%>:</strong> %s<br />' +
  322. '<strong><%:Channel%>:</strong> %d (%.3f <%:GHz%>)<br />' +
  323. '<strong><%:Bitrate%>:</strong> %s <%:Mbit/s%><br />',
  324. icon, net.signal, net.noise,
  325. net.quality,
  326. net.link, net.ssid,
  327. net.mode,
  328. net.channel, net.frequency,
  329. net.bitrate || '?'
  330. );
  331. if (is_assoc)
  332. {
  333. s += String.format(
  334. '<strong><%:BSSID%>:</strong> %s<br />' +
  335. '<strong><%:Encryption%>:</strong> %s',
  336. net.bssid,
  337. net.encryption
  338. );
  339. }
  340. else
  341. {
  342. s += '<em><%:Wireless is disabled or not associated%></em>';
  343. }
  344. s += '</small></td></tr></table>';
  345. for (var bssid in net.assoclist)
  346. {
  347. assoclist.push({
  348. bssid: bssid,
  349. signal: net.assoclist[bssid].signal,
  350. noise: net.assoclist[bssid].noise,
  351. rx_rate: net.assoclist[bssid].rx_rate,
  352. rx_mcs: net.assoclist[bssid].rx_mcs,
  353. rx_40mhz: net.assoclist[bssid].rx_40mhz,
  354. tx_rate: net.assoclist[bssid].tx_rate,
  355. tx_mcs: net.assoclist[bssid].tx_mcs,
  356. tx_40mhz: net.assoclist[bssid].tx_40mhz,
  357. link: net.link,
  358. name: net.name
  359. });
  360. }
  361. }
  362. if (!s)
  363. s = '<em><%:No information available%></em>';
  364. td.innerHTML = s;
  365. }
  366. }
  367. var ac = document.getElementById('wifi_assoc_table');
  368. if (ac)
  369. {
  370. /* clear all rows */
  371. while( ac.rows.length > 1 )
  372. ac.rows[0].parentNode.deleteRow(1);
  373. assoclist.sort(function(a, b) {
  374. return (a.name == b.name)
  375. ? (a.bssid < b.bssid)
  376. : (a.name > b.name )
  377. ;
  378. });
  379. for( var i = 0; i < assoclist.length; i++ )
  380. {
  381. var tr = ac.rows[0].parentNode.insertRow(-1);
  382. tr.className = 'cbi-section-table-row cbi-rowstyle-' + (1 + (i % 2));
  383. var icon;
  384. var q = (-1 * (assoclist[i].noise - assoclist[i].signal)) / 5;
  385. if (q < 1)
  386. icon = "<%=resource%>/icons/signal-0.png";
  387. else if (q < 2)
  388. icon = "<%=resource%>/icons/signal-0-25.png";
  389. else if (q < 3)
  390. icon = "<%=resource%>/icons/signal-25-50.png";
  391. else if (q < 4)
  392. icon = "<%=resource%>/icons/signal-50-75.png";
  393. else
  394. icon = "<%=resource%>/icons/signal-75-100.png";
  395. tr.insertCell(-1).innerHTML = String.format(
  396. '<img src="%s" title="<%:Signal%>: %d <%:dBm%> / <%:Noise%>: %d <%:dBm%>" />',
  397. icon, assoclist[i].signal, assoclist[i].noise
  398. );
  399. tr.insertCell(-1).innerHTML = assoclist[i].bssid;
  400. tr.insertCell(-1).innerHTML = String.format(
  401. '<a href="%s">%s</a>',
  402. assoclist[i].link,
  403. '%h'.format(assoclist[i].name).nobr()
  404. );
  405. tr.insertCell(-1).innerHTML = String.format('%d <%:dBm%>', assoclist[i].signal).nobr();
  406. tr.insertCell(-1).innerHTML = String.format('%d <%:dBm%>', assoclist[i].noise).nobr();
  407. tr.insertCell(-1).innerHTML = (assoclist[i].rx_mcs > -1)
  408. ? String.format('%.1f <%:Mbit/s%>, MCS %d, %d<%:MHz%>', assoclist[i].rx_rate / 1000, assoclist[i].rx_mcs, assoclist[i].rx_40mhz ? 40 : 20).nobr()
  409. : String.format('%.1f <%:Mbit/s%>', assoclist[i].rx_rate / 1000).nobr()
  410. ;
  411. tr.insertCell(-1).innerHTML = (assoclist[i].tx_mcs > -1)
  412. ? String.format('%.1f <%:Mbit/s%>, MCS %d, %d<%:MHz%>', assoclist[i].tx_rate / 1000, assoclist[i].tx_mcs, assoclist[i].tx_40mhz ? 40 : 20).nobr()
  413. : String.format('%.1f <%:Mbit/s%>', assoclist[i].tx_rate / 1000).nobr()
  414. ;
  415. }
  416. if (ac.rows.length == 1)
  417. {
  418. var tr = ac.rows[0].parentNode.insertRow(-1);
  419. tr.className = 'cbi-section-table-row';
  420. var td = tr.insertCell(-1);
  421. td.colSpan = 7;
  422. td.innerHTML = '<br /><em><%:No information available%></em>';
  423. }
  424. }
  425. <% end %>
  426. var e;
  427. if (e = document.getElementById('localtime'))
  428. e.innerHTML = info.localtime;
  429. if (e = document.getElementById('uptime'))
  430. e.innerHTML = String.format('%t', info.uptime);
  431. if (e = document.getElementById('loadavg'))
  432. e.innerHTML = String.format(
  433. '%.02f, %.02f, %.02f',
  434. info.loadavg[0] / 65535.0,
  435. info.loadavg[1] / 65535.0,
  436. info.loadavg[2] / 65535.0
  437. );
  438. if (e = document.getElementById('memtotal'))
  439. e.innerHTML = progressbar(
  440. ((info.memory.free + info.memory.buffered) / 1024) + " <%:kB%>",
  441. (info.memory.total / 1024) + " <%:kB%>"
  442. );
  443. if (e = document.getElementById('memfree'))
  444. e.innerHTML = progressbar(
  445. (info.memory.free / 1024) + " <%:kB%>",
  446. (info.memory.total / 1024) + " <%:kB%>"
  447. );
  448. if (e = document.getElementById('membuff'))
  449. e.innerHTML = progressbar(
  450. (info.memory.buffered / 1024) + " <%:kB%>",
  451. (info.memory.total / 1024) + " <%:kB%>"
  452. );
  453. if (e = document.getElementById('swaptotal'))
  454. e.innerHTML = progressbar(
  455. (info.swap.free / 1024) + " <%:kB%>",
  456. (info.swap.total / 1024) + " <%:kB%>"
  457. );
  458. if (e = document.getElementById('swapfree'))
  459. e.innerHTML = progressbar(
  460. (info.swap.free / 1024) + " <%:kB%>",
  461. (info.swap.total / 1024) + " <%:kB%>"
  462. );
  463. if (e = document.getElementById('conns'))
  464. e.innerHTML = progressbar(info.conncount, info.connmax);
  465. }
  466. );
  467. //]]></script>
  468. <h2><a id="content" name="content"><%:Status%></a></h2>
  469. <fieldset class="cbi-section">
  470. <legend><%:System%></legend>
  471. <table width="100%" cellspacing="10">
  472. <tr><td width="33%"><%:Hostname%></td><td><%=luci.sys.hostname() or "?"%></td></tr>
  473. <tr><td width="33%"><%:Model%></td><td><%=pcdata(boardinfo.model or boardinfo.system or "?")%></td></tr>
  474. <tr><td width="33%"><%:Firmware Version%></td><td>
  475. <%=pcdata(ver.distname)%> <%=pcdata(ver.distversion)%> /
  476. <%=pcdata(ver.luciname)%> (<%=pcdata(ver.luciversion)%>)
  477. </td></tr>
  478. <tr><td width="33%"><%:Kernel Version%></td><td><%=unameinfo.release or "?"%></td></tr>
  479. <tr><td width="33%"><%:Local Time%></td><td id="localtime">-</td></tr>
  480. <tr><td width="33%"><%:Uptime%></td><td id="uptime">-</td></tr>
  481. <tr><td width="33%"><%:Load Average%></td><td id="loadavg">-</td></tr>
  482. </table>
  483. </fieldset>
  484. <fieldset class="cbi-section">
  485. <legend><%:Memory%></legend>
  486. <table width="100%" cellspacing="10">
  487. <tr><td width="33%"><%:Total Available%></td><td id="memtotal">-</td></tr>
  488. <tr><td width="33%"><%:Free%></td><td id="memfree">-</td></tr>
  489. <tr><td width="33%"><%:Buffered%></td><td id="membuff">-</td></tr>
  490. </table>
  491. </fieldset>
  492. <% if swapinfo.total > 0 then %>
  493. <fieldset class="cbi-section">
  494. <legend><%:Swap%></legend>
  495. <table width="100%" cellspacing="10">
  496. <tr><td width="33%"><%:Total Available%></td><td id="swaptotal">-</td></tr>
  497. <tr><td width="33%"><%:Free%></td><td id="swapfree">-</td></tr>
  498. </table>
  499. </fieldset>
  500. <% end %>
  501. <fieldset class="cbi-section">
  502. <legend><%:Network%></legend>
  503. <table width="100%" cellspacing="10">
  504. <tr><td width="33%" style="vertical-align:top"><%:IPv4 WAN Status%></td><td>
  505. <table><tr>
  506. <td id="wan4_i" style="width:16px; text-align:center; padding:3px"><img src="<%=resource%>/icons/ethernet_disabled.png" /><br /><small>?</small></td>
  507. <td id="wan4_s" style="vertical-align:middle; padding: 3px"><em><%:Collecting data...%></em></td>
  508. </tr></table>
  509. </td></tr>
  510. <% if has_ipv6 then %>
  511. <tr><td width="33%" style="vertical-align:top"><%:IPv6 WAN Status%></td><td>
  512. <table><tr>
  513. <td id="wan6_i" style="width:16px; text-align:center; padding:3px"><img src="<%=resource%>/icons/ethernet_disabled.png" /><br /><small>?</small></td>
  514. <td id="wan6_s" style="vertical-align:middle; padding: 3px"><em><%:Collecting data...%></em></td>
  515. </tr></table>
  516. </td></tr>
  517. <% end %>
  518. <tr><td width="33%"><%:Active Connections%></td><td id="conns">-</td></tr>
  519. </table>
  520. </fieldset>
  521. <% if has_dhcp then %>
  522. <fieldset class="cbi-section">
  523. <legend><%:DHCP Leases%></legend>
  524. <table class="cbi-section-table" id="lease_status_table">
  525. <tr class="cbi-section-table-titles">
  526. <th class="cbi-section-table-cell"><%:Hostname%></th>
  527. <th class="cbi-section-table-cell"><%:IPv4-Address%></th>
  528. <th class="cbi-section-table-cell"><%:MAC-Address%></th>
  529. <th class="cbi-section-table-cell"><%:Leasetime remaining%></th>
  530. </tr>
  531. <tr class="cbi-section-table-row">
  532. <td colspan="4"><em><br /><%:Collecting data...%></em></td>
  533. </tr>
  534. </table>
  535. </fieldset>
  536. <fieldset class="cbi-section" style="display:none">
  537. <legend><%:DHCPv6 Leases%></legend>
  538. <table class="cbi-section-table" id="lease6_status_table">
  539. <tr class="cbi-section-table-titles">
  540. <th class="cbi-section-table-cell"><%:Hostname%></th>
  541. <th class="cbi-section-table-cell"><%:IPv6-Address%></th>
  542. <th class="cbi-section-table-cell"><%:DUID%></th>
  543. <th class="cbi-section-table-cell"><%:Leasetime remaining%></th>
  544. </tr>
  545. <tr class="cbi-section-table-row">
  546. <td colspan="4"><em><br /><%:Collecting data...%></em></td>
  547. </tr>
  548. </table>
  549. </fieldset>
  550. <% end %>
  551. <% if has_dsl then %>
  552. <fieldset class="cbi-section">
  553. <legend><%:ADSL%></legend>
  554. <table width="100%" cellspacing="10">
  555. <tr><td width="33%" style="vertical-align:top"><%:ADSL Status%></td><td>
  556. <table><tr>
  557. <td id="dsl_i" style="width:16px; text-align:center; padding:3px"><img src="<%=resource%>/icons/ethernet_disabled.png" /><br /><small>?</small></td>
  558. <td id="dsl_s" style="vertical-align:middle; padding: 3px"><em><%:Collecting data...%></em></td>
  559. </tr></table>
  560. </td></tr>
  561. </table>
  562. </fieldset>
  563. <% end %>
  564. <% if has_wifi then %>
  565. <fieldset class="cbi-section">
  566. <legend><%:Wireless%></legend>
  567. <table id="wifi_status_table" width="100%" cellspacing="10">
  568. <tr><td><em><%:Collecting data...%></em></td></tr>
  569. </table>
  570. </fieldset>
  571. <fieldset class="cbi-section">
  572. <legend><%:Associated Stations%></legend>
  573. <table class="cbi-section-table" id="wifi_assoc_table">
  574. <tr class="cbi-section-table-titles">
  575. <th class="cbi-section-table-cell">&#160;</th>
  576. <th class="cbi-section-table-cell"><%:MAC-Address%></th>
  577. <th class="cbi-section-table-cell"><%:Network%></th>
  578. <th class="cbi-section-table-cell"><%:Signal%></th>
  579. <th class="cbi-section-table-cell"><%:Noise%></th>
  580. <th class="cbi-section-table-cell"><%:RX Rate%></th>
  581. <th class="cbi-section-table-cell"><%:TX Rate%></th>
  582. </tr>
  583. <tr class="cbi-section-table-row">
  584. <td colspan="7"><em><br /><%:Collecting data...%></em></td>
  585. </tr>
  586. </table>
  587. </fieldset>
  588. <% end %>
  589. <%-
  590. local incdir = util.libpath() .. "/view/admin_status/index/"
  591. if fs.access(incdir) then
  592. local inc
  593. for inc in fs.dir(incdir) do
  594. if inc:match("%.htm$") then
  595. include("admin_status/index/" .. inc:gsub("%.htm$", ""))
  596. end
  597. end
  598. end
  599. -%>
  600. <%+footer%>