summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--modules/luci-base/luasrc/controller/admin/index.lua18
-rw-r--r--modules/luci-base/luasrc/view/wifi_assoclist.htm40
2 files changed, 57 insertions, 1 deletions
diff --git a/modules/luci-base/luasrc/controller/admin/index.lua b/modules/luci-base/luasrc/controller/admin/index.lua
index 39004c6760..1f7db0cb38 100644
--- a/modules/luci-base/luasrc/controller/admin/index.lua
+++ b/modules/luci-base/luasrc/controller/admin/index.lua
@@ -80,6 +80,9 @@ function index()
if has_wifi then
page = entry({"admin", "wireless_assoclist"}, call("wifi_assoclist"), nil)
page.leaf = true
+
+ page = entry({"admin", "wireless_deauth"}, post("wifi_deauth"), nil)
+ page.leaf = true
end
page = entry({"admin", "translations"}, call("action_translations"), nil)
@@ -144,3 +147,18 @@ function wifi_assoclist()
luci.http.prepare_content("application/json")
luci.http.write_json(s.wifi_assoclist())
end
+
+function wifi_deauth()
+ local iface = luci.http.formvalue("iface")
+ local bssid = luci.http.formvalue("bssid")
+
+ if iface and bssid then
+ luci.util.ubus("hostapd.%s" % iface, "del_client", {
+ addr = bssid,
+ deauth = true,
+ reason = 5,
+ ban_time = 60000
+ })
+ end
+ luci.http.status(200, "OK")
+end
diff --git a/modules/luci-base/luasrc/view/wifi_assoclist.htm b/modules/luci-base/luasrc/view/wifi_assoclist.htm
index 700d998ad8..b7147bfb71 100644
--- a/modules/luci-base/luasrc/view/wifi_assoclist.htm
+++ b/modules/luci-base/luasrc/view/wifi_assoclist.htm
@@ -1,4 +1,21 @@
+<%
+ local supports_deauth = {}
+
+ local _, v
+ for _, v in ipairs(luci.util.ubus()) do
+ local iface = v:match("^hostapd%.(.+)$")
+ if iface then
+ local funcs = luci.util.ubus(v)
+ if type(funcs) == "table" and funcs.del_client then
+ supports_deauth[iface] = true
+ end
+ end
+ end
+%>
+
<script type="text/javascript">//<![CDATA[
+ var supports_deauth = <%= luci.http.write_json(supports_deauth) %>;
+
function wifirate(bss, rx) {
var p = rx ? 'rx_' : 'tx_',
s = '%.1f <%:Mbit/s%>, %d<%:MHz%>'
@@ -17,6 +34,16 @@
return s;
}
+ function handleDeauth(ev) {
+ (new XHR()).post('<%=url('admin/wireless_deauth')%>', {
+ token: '<%=token%>',
+ iface: ev.target.getAttribute('data-iface'),
+ bssid: ev.target.getAttribute('data-bssid')
+ }, function() {
+ ev.target.disabled = true;
+ });
+ }
+
XHR.poll(5, '<%=url('admin/wireless_assoclist')%>', null,
function(x, st)
{
@@ -58,7 +85,15 @@
E('span', wifirate(bss, true)),
E('br'),
E('span', wifirate(bss, false))
- ])
+ ]),
+ supports_deauth[bss.ifname] ? E('input', {
+ type: 'button',
+ class: 'cbi-button cbi-button-remove',
+ value: '<%:Disconnect%>',
+ 'data-bssid': bss.bssid,
+ 'data-iface': bss.ifname,
+ click: handleDeauth
+ }) : '-'
]);
});
@@ -75,6 +110,9 @@
<div class="th nowrap"><%:Host%></div>
<div class="th nowrap"><%:Signal%> / <%:Noise%></div>
<div class="th nowrap"><%:RX Rate%> / <%:TX Rate%></div>
+ <% if next(supports_deauth) then %>
+ <div class="th right"><%:Disconnect%></div>
+ <% end %>
</div>
<div class="tr placeholder">
<div class="td"><em><%:Collecting data...%></em></div>