applications/luci-upnp: enable/disable service, live status, allow removing single forwards
This commit is contained in:
parent
9663c7cf2e
commit
b8f810092b
2 changed files with 142 additions and 6 deletions
|
@ -19,12 +19,64 @@ function index()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local page = entry({"admin", "services", "upnp"}, cbi("upnp/upnp"), "UPNP")
|
local page
|
||||||
|
|
||||||
|
page = entry({"admin", "services", "upnp"}, cbi("upnp/upnp"), "UPNP")
|
||||||
page.i18n = "upnp"
|
page.i18n = "upnp"
|
||||||
page.dependent = true
|
page.dependent = true
|
||||||
|
|
||||||
|
page = entry({"mini", "network", "upnp"}, cbi("upnp/upnpmini", {autoapply=true}), "UPNP")
|
||||||
local page = entry({"mini", "network", "upnp"}, cbi("upnp/upnpmini", {autoapply=true}), "UPNP")
|
|
||||||
page.i18n = "upnp"
|
page.i18n = "upnp"
|
||||||
page.dependent = true
|
page.dependent = true
|
||||||
|
|
||||||
|
entry({"admin", "services", "upnp", "status"}, call("act_status")).leaf = true
|
||||||
|
entry({"admin", "services", "upnp", "delete"}, call("act_delete")).leaf = true
|
||||||
|
end
|
||||||
|
|
||||||
|
function act_status()
|
||||||
|
local ipt = io.popen("iptables --line-numbers -t nat -xnvL MINIUPNPD")
|
||||||
|
if ipt then
|
||||||
|
local fwd = { }
|
||||||
|
while true do
|
||||||
|
local ln = ipt:read("*l")
|
||||||
|
if not ln then
|
||||||
|
break
|
||||||
|
elseif ln:match("^%d+") then
|
||||||
|
local num, proto, extport, intaddr, intport =
|
||||||
|
ln:match("^(%d+).-([a-z]+).-dpt:(%d+) to:(%S-):(%d+)")
|
||||||
|
|
||||||
|
if num and proto and extport and intaddr and intport then
|
||||||
|
num = tonumber(num)
|
||||||
|
extport = tonumber(extport)
|
||||||
|
intport = tonumber(intport)
|
||||||
|
|
||||||
|
fwd[#fwd+1] = {
|
||||||
|
num = num,
|
||||||
|
proto = proto:upper(),
|
||||||
|
extport = extport,
|
||||||
|
intaddr = intaddr,
|
||||||
|
intport = intport
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ipt:close()
|
||||||
|
|
||||||
|
luci.http.prepare_content("application/json")
|
||||||
|
luci.http.write_json(fwd)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function act_delete()
|
||||||
|
local path = luci.dispatcher.context.requestpath
|
||||||
|
local idx = tonumber(path[#path])
|
||||||
|
|
||||||
|
if idx and idx > 0 then
|
||||||
|
luci.sys.call("iptables -t filter -D MINIUPNPD %d 2>/dev/null" % idx)
|
||||||
|
luci.sys.call("iptables -t nat -D MINIUPNPD %d 2>/dev/null" % idx)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
luci.http.status(400, "Bad request")
|
||||||
end
|
end
|
84
applications/luci-upnp/luasrc/view/upnp_status.htm
Normal file
84
applications/luci-upnp/luasrc/view/upnp_status.htm
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
<script type="text/javascript"><![CDATA[
|
||||||
|
|
||||||
|
|
||||||
|
function upnp_delete_fwd(idx) {
|
||||||
|
var dlxhr = new XHR();
|
||||||
|
|
||||||
|
dlxhr.get('<%=luci.dispatcher.build_url("admin", "services", "upnp", "delete")%>/' + idx, null,
|
||||||
|
function(x)
|
||||||
|
{
|
||||||
|
var tb = document.getElementById('upnp_status_table');
|
||||||
|
if (tb && (idx < tb.rows.length))
|
||||||
|
tb.rows[0].parentNode.removeChild(tb.rows[idx]);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
var stxhr = new XHR();
|
||||||
|
(function() {
|
||||||
|
stxhr.get('<%=luci.dispatcher.build_url("admin", "services", "upnp", "status")%>', null,
|
||||||
|
function(x)
|
||||||
|
{
|
||||||
|
var st = x.responseText ? eval('(' + x.responseText + ')') : null;
|
||||||
|
var tb = document.getElementById('upnp_status_table');
|
||||||
|
|
||||||
|
if (st && tb)
|
||||||
|
{
|
||||||
|
/* clear all rows */
|
||||||
|
while( tb.rows.length > 1 )
|
||||||
|
tb.rows[1].parentNode.removeChild(tb.rows[1]);
|
||||||
|
|
||||||
|
for( var i = 0; i < st.length; i++ )
|
||||||
|
{
|
||||||
|
var tr = document.createElement('tr');
|
||||||
|
tr.className = 'cbi-section-table-row cbi-rowstyle-' + ((i % 2) + 1);
|
||||||
|
|
||||||
|
tr.innerHTML = String.format(
|
||||||
|
'<td class="cbi-section-table-cell">%s</td>' +
|
||||||
|
'<td class="cbi-section-table-cell">%d</td>' +
|
||||||
|
'<td class="cbi-section-table-cell">%s</td>' +
|
||||||
|
'<td class="cbi-section-table-cell">%d</td>' +
|
||||||
|
'<td class="cbi-section-table-cell">' +
|
||||||
|
'<input class="cbi-input-remove" type="button" value="<%:Delete Redirect%>" onclick="upnp_delete_fwd(%d)" />' +
|
||||||
|
'</td>',
|
||||||
|
st[i].proto,
|
||||||
|
st[i].extport,
|
||||||
|
st[i].intaddr,
|
||||||
|
st[i].intport,
|
||||||
|
st[i].num
|
||||||
|
);
|
||||||
|
|
||||||
|
tb.rows[0].parentNode.appendChild(tr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( tb.rows.length == 1 )
|
||||||
|
{
|
||||||
|
var tr = document.createElement('tr');
|
||||||
|
tr.className = 'cbi-section-table-row';
|
||||||
|
tr.innerHTML = '<td colspan="5"><em><br /><%:There are no active redirects.%></em></td>';
|
||||||
|
|
||||||
|
tb.rows[0].parentNode.appendChild(tr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
window.setTimeout(arguments.callee, 5000);
|
||||||
|
})();
|
||||||
|
]]></script>
|
||||||
|
|
||||||
|
<fieldset class="cbi-section">
|
||||||
|
<legend><%:Active UPnP Redirects%></legend>
|
||||||
|
<table class="cbi-section-table" id="upnp_status_table">
|
||||||
|
<tr class="cbi-section-table-titles">
|
||||||
|
<th class="cbi-section-table-cell"><%:Protocol%></th>
|
||||||
|
<th class="cbi-section-table-cell"><%:External Port%></th>
|
||||||
|
<th class="cbi-section-table-cell"><%:Client Address%></th>
|
||||||
|
<th class="cbi-section-table-cell"><%:Client Port%></th>
|
||||||
|
<th class="cbi-section-table-cell"> </th>
|
||||||
|
</tr>
|
||||||
|
<tr class="cbi-section-table-row">
|
||||||
|
<td colspan="5"><em><br /><%:Collecting data...%></em></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</fieldset>
|
Loading…
Reference in a new issue