diff options
Diffstat (limited to 'applications')
44 files changed, 3815 insertions, 185 deletions
diff --git a/applications/luci-app-clamav/po/ja/clamav.po b/applications/luci-app-clamav/po/ja/clamav.po new file mode 100644 index 0000000000..c54c7b18aa --- /dev/null +++ b/applications/luci-app-clamav/po/ja/clamav.po @@ -0,0 +1,130 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.12\n" +"Last-Translator: INAGAKI Hiroshi <musashino.open@gmail.com>\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"Language: ja\n" + +msgid "10" +msgstr "10" + +msgid "1024" +msgstr "1024" + +msgid "15" +msgstr "15" + +msgid "150M" +msgstr "150M" + +msgid "1M" +msgstr "1M" + +msgid "20" +msgstr "20" + +msgid "2048" +msgstr "2048" + +msgid "2M" +msgstr "2M" + +msgid "50M" +msgstr "50M" + +msgid "512K" +msgstr "512K" + +msgid "600" +msgstr "600" + +msgid "Block encrypted archives" +msgstr "暗号化されたアーカイブのブロック" + +msgid "ClamAV" +msgstr "ClamAV" + +msgid "Database check every N sec" +msgstr "データベース チェック間隔(秒)" + +msgid "Detect broken executables" +msgstr "破損した実行ファイルの検出" + +msgid "Detect possibly unwanted apps" +msgstr "不必要と思われるアプリケーションの検出" + +msgid "Enable verbose logging" +msgstr "詳細なログの有効化" + +msgid "Follow directory symlinks" +msgstr "ディレクトリ シンボリックリンクに従う" + +msgid "Follow file symlinks" +msgstr "ファイル シンボリックリンクに従う" + +msgid "Log" +msgstr "ログ" + +msgid "Log additional infection info" +msgstr "追加の感染情報ログ" + +msgid "Log time with each message" +msgstr "ログ メッセージ毎に時刻を付加" + +msgid "Max directory scan depth" +msgstr "ディレクトリ スキャンの最大深度" + +msgid "Max number of threads" +msgstr "スレッドの最大数" + +msgid "Max size of log file" +msgstr "ログの最大サイズ" + +msgid "Max size of scanned file" +msgstr "" + +msgid "No" +msgstr "いいえ" + +msgid "Port range, highest port" +msgstr "ポート範囲(上限)" + +msgid "Port range, lowest port" +msgstr "ポート範囲(下限)" + +msgid "Scan ELF files" +msgstr "ELF ファイルのスキャン" + +msgid "Scan MS Office and .msi files" +msgstr "MS Office と .msi ファイルのスキャン" + +msgid "Scan RFC1341 messages split over many emails" +msgstr "" + +msgid "Scan archives" +msgstr "アーカイブのスキャン" + +msgid "Scan emails" +msgstr "E-mailのスキャン" + +msgid "Scan pdf files" +msgstr "PDF ファイルのスキャン" + +msgid "Scan portable executables" +msgstr "ポータブル 実行ファイルのスキャン" + +msgid "Scan swf files" +msgstr "SWF ファイルのスキャン" + +msgid "Settings" +msgstr "設定" + +msgid "Yes" +msgstr "はい" diff --git a/applications/luci-app-clamav/po/templates/clamav.pot b/applications/luci-app-clamav/po/templates/clamav.pot new file mode 100644 index 0000000000..768f73093a --- /dev/null +++ b/applications/luci-app-clamav/po/templates/clamav.pot @@ -0,0 +1,119 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +msgid "10" +msgstr "" + +msgid "1024" +msgstr "" + +msgid "15" +msgstr "" + +msgid "150M" +msgstr "" + +msgid "1M" +msgstr "" + +msgid "20" +msgstr "" + +msgid "2048" +msgstr "" + +msgid "2M" +msgstr "" + +msgid "50M" +msgstr "" + +msgid "512K" +msgstr "" + +msgid "600" +msgstr "" + +msgid "Block encrypted archives" +msgstr "" + +msgid "ClamAV" +msgstr "" + +msgid "Database check every N sec" +msgstr "" + +msgid "Detect broken executables" +msgstr "" + +msgid "Detect possibly unwanted apps" +msgstr "" + +msgid "Enable verbose logging" +msgstr "" + +msgid "Follow directory symlinks" +msgstr "" + +msgid "Follow file symlinks" +msgstr "" + +msgid "Log" +msgstr "" + +msgid "Log additional infection info" +msgstr "" + +msgid "Log time with each message" +msgstr "" + +msgid "Max directory scan depth" +msgstr "" + +msgid "Max number of threads" +msgstr "" + +msgid "Max size of log file" +msgstr "" + +msgid "Max size of scanned file" +msgstr "" + +msgid "No" +msgstr "" + +msgid "Port range, highest port" +msgstr "" + +msgid "Port range, lowest port" +msgstr "" + +msgid "Scan ELF files" +msgstr "" + +msgid "Scan MS Office and .msi files" +msgstr "" + +msgid "Scan RFC1341 messages split over many emails" +msgstr "" + +msgid "Scan archives" +msgstr "" + +msgid "Scan emails" +msgstr "" + +msgid "Scan pdf files" +msgstr "" + +msgid "Scan portable executables" +msgstr "" + +msgid "Scan swf files" +msgstr "" + +msgid "Settings" +msgstr "" + +msgid "Yes" +msgstr "" diff --git a/applications/luci-app-cshark/Makefile b/applications/luci-app-cshark/Makefile new file mode 100644 index 0000000000..40b0e9fb7f --- /dev/null +++ b/applications/luci-app-cshark/Makefile @@ -0,0 +1,17 @@ +# +# Copyright (C) 2017 Dan Luedtke <mail@danrl.com> +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=Cloudshark capture tool Web UI +LUCI_DEPENDS:=+cshark +LUCI_PKGARCH:=all + +PKG_MAINTAINER:=Luka Perkov <luka@openwrt.org> + +include ../../luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/applications/luci-app-cshark/luasrc/controller/cshark.lua b/applications/luci-app-cshark/luasrc/controller/cshark.lua new file mode 100644 index 0000000000..4d9bbba290 --- /dev/null +++ b/applications/luci-app-cshark/luasrc/controller/cshark.lua @@ -0,0 +1,125 @@ +--[[ +LuCI - Lua Configuration Interface + +Copyright (C) 2014, QA Cafe, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +]]-- + +module("luci.controller.cshark", package.seeall) + +function index() + page = node("admin", "network", "cloudshark") + page.target = cbi("admin_network/cshark") + page.title = _("CloudShark") + page.order = 70 + + page = entry({"admin", "network", "cshark_iface_dump_start"}, call("cshark_iface_dump_start"), nil) + page.leaf = true + + page = entry({"admin", "network", "cshark_iface_dump_stop"}, call("cshark_iface_dump_stop"), nil) + page.leaf = true + + page = entry({"admin", "network", "cshark_check_status"}, call("cshark_check_status"), nil) + page.leaf = true + + page = entry({"admin", "network", "cshark_link_list_get"}, call("cshark_link_list_get"), nil) + page.leaf = true + + page = entry({"admin", "network", "cshark_link_list_clear"}, call("cshark_link_list_clear"), nil) + page.leaf = true +end + +function cshark_iface_dump_start(ifname, value, flag, filter) + if ifname == nil or ifname == '' then + ifname = 'any' + end + if tonumber(value) == nil + then + value = '0' + end + if filter == nil or filter == '' then + filter = '' + end + + if flag == nil or flag == '' then + filter = 'T' + end + + luci.http.prepare_content("text/plain") + + local res = os.execute("(/sbin/cshark -i " .. ifname .. " -" .. flag .. " " .. value .. " -p /tmp/cshark-luci.pid " .. filter .. " > /tmp/cshark-luci.out 2>&1) &") + luci.http.write(tostring(res)) +end + +function cshark_iface_dump_stop() + luci.http.prepare_content("text/plain") + + local f = io.open("/tmp/cshark-luci.pid", "rb") + local pid = f:read("*all") + io.close(f) + + local res = os.execute("kill -TERM " .. pid) + luci.http.write(tostring(res)) +end + +function cshark_check_status() + + local msg = ""; + local status; + local f = io.open("/tmp/cshark-luci.pid","r") + if f ~= nil then + status = 1; + io.close(f) + else + status = 0; + end + + f = io.open("/tmp/cshark-luci.out","r") + if f ~= nil then + msg = f:read("*all") + io.close(f) + if msg ~= '' then + os.remove('/tmp/cshark-luci.out') + end + end + + luci.http.prepare_content("application/json") + + local res = {} + res["status"] = status; + res["msg"] = msg; + + luci.http.write_json(res) +end + +function cshark_link_list_get() + local uci = require("uci").cursor() + + luci.http.prepare_content("application/json") + + luci.http.write("[") + + local t = uci:get("cshark", "cshark", "entry") + if (t ~= nil) then + for i = #t, 1, -1 do + luci.http.write("[\"" .. t[i] .. "\"],") + end + end + + luci.http.write("[]]") +end + +function cshark_link_list_clear() + local uci = require("uci").cursor() + + uci:delete("cshark", "cshark", "entry") + uci:commit("cshark"); + + luci.http.status(200, "OK") +end diff --git a/applications/luci-app-cshark/luasrc/model/cbi/admin_network/cshark.lua b/applications/luci-app-cshark/luasrc/model/cbi/admin_network/cshark.lua new file mode 100644 index 0000000000..8db95596f8 --- /dev/null +++ b/applications/luci-app-cshark/luasrc/model/cbi/admin_network/cshark.lua @@ -0,0 +1,30 @@ +--[[ +LuCI - Lua Configuration Interface + +Copyright (C) 2014, QA Cafe, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +$Id$ +]]-- + +local fs = require "nixio.fs" + +m = Map("cshark", translate("CloudShark")) + +if fs.access("/etc/config/cshark") then + m:section(SimpleSection).template = "cshark" + + s = m:section(TypedSection, "cshark", translate("Options")) + s.anonymous = true + s.addremove = false + + s:option(Value, "url", translate("CloudShark URL")) + s:option(Value, "token", translate("CloudShark API token")) +end + +return m diff --git a/applications/luci-app-cshark/luasrc/view/cshark.htm b/applications/luci-app-cshark/luasrc/view/cshark.htm new file mode 100644 index 0000000000..bc67f806c4 --- /dev/null +++ b/applications/luci-app-cshark/luasrc/view/cshark.htm @@ -0,0 +1,291 @@ +<%# +LuCI - Lua Configuration Interface + +Copyright (C) 2014, QA Cafe, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +$Id$ + +-%> + +<fieldset class="cbi-section"> + <legend><%:Start network capture%></legend> + <div class="cbi-section-node"> + <table class="cbi-section-table"> + <tr> + <th><%:Interface%></th> + <th colspan='2'><%:seconds, packets, bytes%></th> + <th><%:Filter%></th> + <th><%:Actions%></th> + </tr> + <tr> + <td> + <select title="<%:Interface%>" style="width:auto" id="s_interfaces"> + <% + local nixio = require "nixio" + for k, v in ipairs(nixio.getifaddrs()) do + if v.family == "packet" then + %> + <option value="<%=v.name%>"><%=v.name%> </option> + <% + end + end + %> + <option value="any"><%:any%></option> + </select> + </td> + <td colspan='2'> + <input id="tx_value" type="text" value="0" /> + <select title="<%:timeout, bytes, seconds%>" id="s_value_type" style="width:auto"> + <option value="T"><%:seconds%></option> + <option value="P"><%:packets%></option> + <option value="S"><%:bytes%></option> + </select> + </td> + <td> + <input style="margin: 5px 0" type="text" title="<%:Filter%>" placeholder="filter" id="i_filter" /> + </td> + <td> + <input type="button" id="bt_action" data-action="start" value="<%:Start capture%>" class="cbi-button" /> + </td> + </tr> + </table> + </div> +</fieldset> + +<fieldset class="cbi-section"> + <span id="cshark-rc-output"></span> +</fieldset> + +<hr/> + +<fieldset class="cbi-section"> + <legend><%:Capture links%></legend> + <div class="cbi-section-node"> + <table id="t_link_list" class="cbi-section-table"> + <tr class="cbi-section-table-titles"> + <th class="cbi-section-table-cell"><%:Capture URL%></th> + <th class="cbi-section-table-cell"><%:Capture time%></th> + </tr> + </table> + </div> +</fieldset> + +<fieldset class="cbi-section"> + <a href="https://support.cloudshark.org/openwrt/openwrt-cloudshark.html" target="_blank">Visit support.cloudshark.org for help.</a> +</fieldset> + +<hr/> + +<script type="text/javascript" src="<%=resource%>/cbi.js"></script> +<script type="text/javascript">//<![CDATA[ + + var capture_running = 0; + var pid_file = 0; + var bt_action = document.getElementById('bt_action'); + var a_clear_links = document.getElementById('a_clear_links'); + var output = document.getElementById('cshark-rc-output'); + var loader = '<img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" width="16" height="16" style="vertical-align:middle" /> '; + var msg = { 'start' : '<%:Waiting for capture to complete...%>', 'stop' : '<%:Waiting for upload to complete...%>' }; + var status_msg = msg['start']; + + function get_date(timestamp) + { + function pad_str(str) + { + return (str < 10) ? "0" + str : str; + } + + var current_date = new Date(timestamp * 1000); + return current_date.getFullYear() + "-" + + pad_str(current_date.getMonth() + 1) + "-" + + pad_str(current_date.getDate()) + " " + + pad_str(current_date.getHours()) + ":" + + pad_str(current_date.getMinutes()) + ":" + + pad_str(current_date.getSeconds()); + } + + bt_action.onclick = function() + { + var action = this.getAttribute("data-action"); + var csxhr = new XHR(); + + if (action == "stop") + { + update_status(action); + + bt_action.disabled = true; + + csxhr.get('<%=luci.dispatcher.build_url("admin", "network")%>/cshark_iface_dump_stop', null, + function(x) + { + if (!x || x.responseText.trim() != "0") + { + update_status("failed", "Invalid response on stop."); + } + }); + + } + else if (action == "start") + { + + var s_interfaces = document.getElementById('s_interfaces'); + var s_value_type = document.getElementById('s_value_type'); + var i_filter = document.getElementById('i_filter'); + + var if_n = s_interfaces.selectedIndex; + var t_n = s_value_type.selectedIndex; + var ifname = s_interfaces.options[if_n].value.trim(); + var filter_val = i_filter.value.trim(); + var tx_val = document.getElementById('tx_value').value.trim(); + var type_val = s_value_type.options[t_n].value.trim(); + + if (type_val != 'P' && type_val != 'T' && type_val != 'S') type_val = 'T'; + + if (!ifname || !type_val) return; + + if (isNaN(tx_val)) return alert("<%:value for [seconds, packets, bytes] must be Integer%>"); + + update_status(action); + + csxhr.get('<%=luci.dispatcher.build_url("admin", "network")%>/cshark_iface_dump_start/' + ifname + '/' + tx_val + '/' + type_val + '/'+ filter_val, null, + function(x) + { + if (!x) + update_status("failed", "Invalid response on start."); + else + update_status("running"); + }); + } + } + + function update_status(status, message) + { + switch (status) + { + case 'start': + case 'stop': + status_msg = msg[status]; + output.innerHTML = loader + status_msg; + break + + case 'running': + if (capture_running) break;; + + output.innerHTML = loader + status_msg; + + bt_action.value = '<%:Stop capture%>'; + bt_action.setAttribute('data-action', 'stop'); + capture_running = 1; + break; + + case 'completed': + case 'failed': + if (!capture_running) break; + + if (status == "completed") + { + link_list_update(); + } + + output.innerHTML = "<pre>" + message + "</pre>"; + bt_action.value = '<%:Start capture%>'; + bt_action.setAttribute('data-action', 'start'); + bt_action.disabled = false; + capture_running = 0; + break; + } + } + + + function check_status() + { + + XHR.poll(3, '<%=luci.dispatcher.build_url("admin", "network")%>/cshark_check_status', null, + function(x, data) + { + if (!x) + { + if (capture_running) + update_status("failed", "Invalid response when fetching status."); + + return; + } + console.log(data) + + update_status( (data.status == 1) && "running" || "completed", data.msg); + }) + } + + function link_list_clear() + { + var csxhr_del = new XHR(); + csxhr_del.get('<%=luci.dispatcher.build_url("admin", "network")%>/cshark_link_list_clear', null, + function(x) + { + if (!x) + return false; + + link_list_update(); + }); + } + + + function link_list_update() + { + var t_link = document.getElementById("t_link_list"); + if (!t_link) return; + + var row_count = t_link.rows.length; + while(--row_count) t_link.deleteRow(row_count); + + var cell = t_link.insertRow(-1).insertCell(0); + cell.colSpan = 2; + cell.innerHTML = loader; + + var csxhr_link = new XHR(); + csxhr_link.get('<%=luci.dispatcher.build_url("admin", "network")%>/cshark_link_list_get', null, + function(x, entries) + { + var row = t_link.deleteRow(1); + + if (!x) return; + + if (!entries || !entries.length) + { + var cell = t_link.insertRow(-1).insertCell(0); + cell.colSpan = 2; + cell.innerHTML = '<em><br />There are no captures available yet.</em>'; + + return; + } + + for (var i = 0, len = entries.length; i < len ; i++) + { + var entry = entries[i][0]; + if (!entry) continue; + + var data = entry.split(","); + var url = data[0]; + var timestamp = data[1]; + + var row = t_link.insertRow(-1); + row.insertCell(0).innerHTML = '<a href="'+url+'" target="_blank">'+url+'</a>'; + row.insertCell(1).innerHTML = get_date(timestamp); + } + + var cell = t_link.insertRow(-1).insertCell(0); + cell.colSpan = 2; + cell.style.textAlign="center"; + cell.innerHTML = '<input type="button" onclick="link_list_clear()" class="cbi-button" value ="<%:Clear list%>" />'; + }) + } + + check_status(); + link_list_update(); +//]]></script> diff --git a/applications/luci-app-firewall/luasrc/model/cbi/firewall/zones.lua b/applications/luci-app-firewall/luasrc/model/cbi/firewall/zones.lua index 694bbd872e..500e5078f4 100644 --- a/applications/luci-app-firewall/luasrc/model/cbi/firewall/zones.lua +++ b/applications/luci-app-firewall/luasrc/model/cbi/firewall/zones.lua @@ -19,7 +19,6 @@ s.addremove = false s:option(Flag, "syn_flood", translate("Enable SYN-flood protection")) o = s:option(Flag, "drop_invalid", translate("Drop invalid packets")) -o.default = o.enabled p = { s:option(ListValue, "input", translate("Input")), diff --git a/applications/luci-app-mwan3/Makefile b/applications/luci-app-mwan3/Makefile new file mode 100644 index 0000000000..758ec90a04 --- /dev/null +++ b/applications/luci-app-mwan3/Makefile @@ -0,0 +1,18 @@ +# +# Copyright (C) 2017 Dan Luedtke <mail@danrl.com> +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI support for the MWAN3 multiwan hotplug script +LUCI_DEPENDS:=+mwan3 +luci-mod-admin-full +luci-app-firewall +luci-lib-nixio +LUCI_PKGARCH:=all +PKG_LICENSE:=GPLv2 + +PKG_MAINTAINER:=Aedan Renner <chipdankly@gmail.com> + +include ../../luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/applications/luci-app-mwan3/luasrc/controller/mwan3.lua b/applications/luci-app-mwan3/luasrc/controller/mwan3.lua new file mode 100644 index 0000000000..3d5a23dd03 --- /dev/null +++ b/applications/luci-app-mwan3/luasrc/controller/mwan3.lua @@ -0,0 +1,331 @@ +module("luci.controller.mwan3", package.seeall) + +sys = require "luci.sys" +ut = require "luci.util" + +ip = "/usr/bin/ip -4 " + +function index() + if not nixio.fs.access("/etc/config/mwan3") then + return + end + + entry({"admin", "network", "mwan"}, + alias("admin", "network", "mwan", "overview"), + _("Load Balancing"), 600) + + entry({"admin", "network", "mwan", "overview"}, + alias("admin", "network", "mwan", "overview", "overview_interface"), + _("Overview"), 10) + entry({"admin", "network", "mwan", "overview", "overview_interface"}, + template("mwan/overview_interface")) + entry({"admin", "network", "mwan", "overview", "interface_status"}, + call("interfaceStatus")) + entry({"admin", "network", "mwan", "overview", "overview_detailed"}, + template("mwan/overview_detailed")) + entry({"admin", "network", "mwan", "overview", "detailed_status"}, + call("detailedStatus")) + + entry({"admin", "network", "mwan", "configuration"}, + alias("admin", "network", "mwan", "configuration", "interface"), + _("Configuration"), 20) + entry({"admin", "network", "mwan", "configuration", "interface"}, + arcombine(cbi("mwan/interface"), cbi("mwan/interfaceconfig")), + _("Interfaces"), 10).leaf = true + entry({"admin", "network", "mwan", "configuration", "member"}, + arcombine(cbi("mwan/member"), cbi("mwan/memberconfig")), + _("Members"), 20).leaf = true + entry({"admin", "network", "mwan", "configuration", "policy"}, + arcombine(cbi("mwan/policy"), cbi("mwan/policyconfig")), + _("Policies"), 30).leaf = true + entry({"admin", "network", "mwan", "configuration", "rule"}, + arcombine(cbi("mwan/rule"), cbi("mwan/ruleconfig")), + _("Rules"), 40).leaf = true + + entry({"admin", "network", "mwan", "advanced"}, + alias("admin", "network", "mwan", "advanced", "hotplugscript"), + _("Advanced"), 100) + entry({"admin", "network", "mwan", "advanced", "hotplugscript"}, + form("mwan/advanced_hotplugscript")) + entry({"admin", "network", "mwan", "advanced", "mwanconfig"}, + form("mwan/advanced_mwanconfig")) + entry({"admin", "network", "mwan", "advanced", "networkconfig"}, + form("mwan/advanced_networkconfig")) + entry({"admin", "network", "mwan", "advanced", "wirelessconfig"}, + form("mwan/advanced_wirelessconfig")) + entry({"admin", "network", "mwan", "advanced", "diagnostics"}, + template("mwan/advanced_diagnostics")) + entry({"admin", "network", "mwan", "advanced", "diagnostics_display"}, + call("diagnosticsData"), nil).leaf = true + entry({"admin", "network", "mwan", "advanced", "troubleshooting"}, + template("mwan/advanced_troubleshooting")) + entry({"admin", "network", "mwan", "advanced", "troubleshooting_display"}, + call("troubleshootingData")) +end + +function getInterfaceStatus(ruleNumber, interfaceName) + if ut.trim(sys.exec("uci -p /var/state get mwan3." .. interfaceName .. ".enabled")) == "1" then + if ut.trim(sys.exec(ip .. "route list table " .. ruleNumber)) ~= "" then + if ut.trim(sys.exec("uci -p /var/state get mwan3." .. interfaceName .. ".track_ip")) ~= "" then + return "online" + else + return "notMonitored" + end + else + return "offline" + end + else + return "notEnabled" + end +end + +function getInterfaceName() + local ruleNumber, status = 0, "" + uci.cursor():foreach("mwan3", "interface", + function (section) + ruleNumber = ruleNumber+1 + status = status .. section[".name"] .. "[" .. getInterfaceStatus(ruleNumber, section[".name"]) .. "]" + end + ) + return status +end + +function interfaceStatus() + local ntm = require "luci.model.network".init() + + local mArray = {} + + -- overview status + local statusString = getInterfaceName() + if statusString ~= "" then + mArray.wans = {} + wansid = {} + + for wanName, interfaceState in string.gfind(statusString, "([^%[]+)%[([^%]]+)%]") do + local wanInterfaceName = ut.trim(sys.exec("uci -p /var/state get network." .. wanName .. ".ifname")) + if wanInterfaceName == "" then + wanInterfaceName = "X" + end + local wanDeviceLink = ntm:get_interface(wanInterfaceName) + wanDeviceLink = wanDeviceLink and wanDeviceLink:get_network() + wanDeviceLink = wanDeviceLink and wanDeviceLink:adminlink() or "#" + wansid[wanName] = #mArray.wans + 1 + mArray.wans[wansid[wanName]] = { name = wanName, link = wanDeviceLink, ifname = wanInterfaceName, status = interfaceState } + end + end + + -- overview status log + local mwanLog = ut.trim(sys.exec("logread | grep mwan3 | tail -n 50 | sed 'x;1!H;$!d;x'")) + if mwanLog ~= "" then + mArray.mwanlog = { mwanLog } + end + + luci.http.prepare_content("application/json") + luci.http.write_json(mArray) +end + +function detailedStatus() + local mArray = {} + + -- detailed mwan status + local detailStatusInfo = ut.trim(sys.exec("/usr/sbin/mwan3 status")) + if detailStatusInfo ~= "" then + mArray.mwandetail = { detailStatusInfo } + end + + luci.http.prepare_content("application/json") + luci.http.write_json(mArray) +end + +function diagnosticsData(interface, tool, task) + function getInterfaceNumber() + local number = 0 + uci.cursor():foreach("mwan3", "interface", + function (section) + number = number+1 + if section[".name"] == interface then + interfaceNumber = number + end + end + ) + end + + local mArray = {} + + local results = "" + if tool == "service" then + os.execute("/usr/sbin/mwan3 " .. task) + if task == "restart" then + results = "MWAN3 restarted" + elseif task == "stop" then + results = "MWAN3 stopped" + else + results = "MWAN3 started" + end + else + local interfaceDevice = ut.trim(sys.exec("uci -p /var/state get network." .. interface .. ".ifname")) + if interfaceDevice ~= "" then + if tool == "ping" then + local gateway = ut.trim(sys.exec("route -n | awk '{if ($8 == \"" .. interfaceDevice .. "\" && $1 == \"0.0.0.0\" && $3 == \"0.0.0.0\") print $2}'")) + if gateway ~= "" then + if task == "gateway" then + local pingCommand = "ping -c 3 -W 2 -I " .. interfaceDevice .. " " .. gateway + results = pingCommand .. "\n\n" .. sys.exec(pingCommand) + else + local tracked = ut.trim(sys.exec("uci -p /var/state get mwan3." .. interface .. ".track_ip")) + if tracked ~= "" then + for z in tracked:gmatch("[^ ]+") do + local pingCommand = "ping -c 3 -W 2 -I " .. interfaceDevice .. " " .. z + results = results .. pingCommand .. "\n\n" .. sys.exec(pingCommand) .. "\n\n" + end + else + results = "No tracking IP addresses configured on " .. interface + end + end + else + results = "No default gateway for " .. interface .. " found. Default route does not exist or is configured incorrectly" + end + elseif tool == "rulechk" then + getInterfaceNumber() + local rule1 = sys.exec(ip .. "rule | grep $(echo $((" .. interfaceNumber .. " + 1000)))") + local rule2 = sys.exec(ip .. "rule | grep $(echo $((" .. interfaceNumber .. " + 2000)))") + if rule1 ~= "" and rule2 ~= "" then + results = "All required interface IP rules found:\n\n" .. rule1 .. rule2 + elseif rule1 ~= "" or rule2 ~= "" then + results = "Missing 1 of the 2 required interface IP rules\n\n\nRules found:\n\n" .. rule1 .. rule2 + else + results = "Missing both of the required interface IP rules" + end + elseif tool == "routechk" then + getInterfaceNumber() + local routeTable = sys.exec(ip .. "route list table " .. interfaceNumber) + if routeTable ~= "" then + results = "Interface routing table " .. interfaceNumber .. " was found:\n\n" .. routeTable + else + results = "Missing required interface routing table " .. interfaceNumber + end + elseif tool == "hotplug" then + if task == "ifup" then + os.execute("/usr/sbin/mwan3 ifup " .. interface) + results = "Hotplug ifup sent to interface " .. interface .. "..." + else + os.execute("/usr/sbin/mwan3 ifdown " .. interface) + results = "Hotplug ifdown sent to interface " .. interface .. "..." + end + end + else + results = "Unable to perform diagnostic tests on " .. interface .. ". There is no physical or virtual device associated with this interface" + end + end + if results ~= "" then + results = ut.trim(results) + mArray.diagnostics = { results } + end + + luci.http.prepare_content("application/json") + luci.http.write_json(mArray) +end + +function troubleshootingData() + local ver = require "luci.version" + + local mArray = {} + + -- software versions + local wrtRelease = ut.trim(ver.distversion) + if wrtRelease ~= "" then + wrtRelease = "OpenWrt - " .. wrtRelease + else + wrtRelease = "OpenWrt - unknown" + end + local luciRelease = ut.trim(ver.luciversion) + if luciRelease ~= "" then + luciRelease = "\nLuCI - " .. luciRelease + else + luciRelease = "\nLuCI - unknown" + end + local mwanVersion = ut.trim(sys.exec("opkg info mwan3 | grep Version | awk '{print $2}'")) + if mwanVersion ~= "" then + mwanVersion = "\n\nmwan3 - " .. mwanVersion + else + mwanVersion = "\n\nmwan3 - unknown" + end + local mwanLuciVersion = ut.trim(sys.exec("opkg info luci-app-mwan3 | grep Version | awk '{print $2}'")) + if mwanLuciVersion ~= "" then + mwanLuciVersion = "\nmwan3-luci - " .. mwanLuciVersion + else + mwanLuciVersion = "\nmwan3-luci - unknown" + end + mArray.versions = { wrtRelease .. luciRelease .. mwanVersion .. mwanLuciVersion } + + -- mwan config + local mwanConfig = ut.trim(sys.exec("cat /etc/config/mwan3")) + if mwanConfig == "" then + mwanConfig = "No data found" + end + mArray.mwanconfig = { mwanConfig } + + -- network config + local networkConfig = ut.trim(sys.exec("cat /etc/config/network | sed -e 's/.*username.*/ USERNAME HIDDEN/' -e 's/.*password.*/ PASSWORD HIDDEN/'")) + if networkConfig == "" then + networkConfig = "No data found" + end + mArray.netconfig = { networkConfig } + + -- wireless config + local wirelessConfig = ut.trim(sys.exec("cat /etc/config/wireless | sed -e 's/.*username.*/ USERNAME HIDDEN/' -e 's/.*password.*/ PASSWORD HIDDEN/' -e 's/.*key.*/ KEY HIDDEN/'")) + if wirelessConfig == "" then + wirelessConfig = "No data found" + end + mArray.wificonfig = { wirelessConfig } + + -- ifconfig + local ifconfig = ut.trim(sys.exec("ifconfig")) + if ifconfig == "" then + ifconfig = "No data found" + end + mArray.ifconfig = { ifconfig } + + -- route -n + local routeShow = ut.trim(sys.exec("route -n")) + if routeShow == "" then + routeShow = "No data found" + end + mArray.routeshow = { routeShow } + + -- ip rule show + local ipRuleShow = ut.trim(sys.exec(ip .. "rule show")) + if ipRuleShow == "" then + ipRuleShow = "No data found" + end + mArray.iprule = { ipRuleShow } + + -- ip route list table 1-250 + local routeList, routeString = ut.trim(sys.exec(ip .. "rule | sed 's/://g' | awk '$1>=2001 && $1<=2250' | awk '{print $NF}'")), "" + if routeList ~= "" then + for line in routeList:gmatch("[^\r\n]+") do + routeString = routeString .. line .. "\n" .. sys.exec(ip .. "route list table " .. line) + end + routeString = ut.trim(routeString) + else + routeString = "No data found" + end + mArray.routelist = { routeString } + + -- default firewall output policy + local firewallOut = ut.trim(sys.exec("uci -p /var/state get firewall.@defaults[0].output")) + if firewallOut == "" then + firewallOut = "No data found" + end + mArray.firewallout = { firewallOut } + + -- iptables + local iptables = ut.trim(sys.exec("iptables -L -t mangle -v -n")) + if iptables == "" then + iptables = "No data found" + end + mArray.iptables = { iptables } + + luci.http.prepare_content("application/json") + luci.http.write_json(mArray) +end diff --git a/applications/luci-app-mwan3/luasrc/model/cbi/mwan/advanced_hotplugscript.lua b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/advanced_hotplugscript.lua new file mode 100644 index 0000000000..0e7b8b11d0 --- /dev/null +++ b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/advanced_hotplugscript.lua @@ -0,0 +1,55 @@ +-- ------ hotplug script configuration ------ -- + +fs = require "nixio.fs" +sys = require "luci.sys" +ut = require "luci.util" + +script = "/etc/hotplug.d/iface/16-mwancustom" +scriptBackup = "/etc/hotplug.d/iface/16-mwancustombak" + +if luci.http.formvalue("cbid.luci.1._restorebak") then -- restore button has been clicked + luci.http.redirect(luci.dispatcher.build_url("admin/network/mwan/advanced/hotplugscript") .. "?restore=yes") +elseif luci.http.formvalue("restore") == "yes" then -- restore script from backup + os.execute("cp -f " .. scriptBackup .. " " .. script) +end + + +m5 = SimpleForm("luci", nil) + m5:append(Template("mwan/advanced_hotplugscript")) -- highlight current tab + +f = m5:section(SimpleSection, nil, + translate("This section allows you to modify the contents of /etc/hotplug.d/iface/16-mwancustom<br />" .. + "This is useful for running system commands and/or scripts based on interface ifup or ifdown hotplug events<br /><br />" .. + "Notes:<br />" .. + "The first line of the script must be "#!/bin/sh" without quotes<br />" .. + "Lines beginning with # are comments and are not executed<br /><br />" .. + "Available variables:<br />" .. + "$ACTION is the hotplug event (ifup, ifdown)<br />" .. + "$INTERFACE is the interface name (wan1, wan2, etc.)<br />" .. + "$DEVICE is the device name attached to the interface (eth0.1, eth1, etc.)")) + + +restore = f:option(Button, "_restorebak", translate("Restore default hotplug script")) + restore.inputtitle = translate("Restore...") + restore.inputstyle = "apply" + +t = f:option(TextValue, "lines") + t.rmempty = true + t.rows = 20 + + function t.cfgvalue() + local hps = fs.readfile(script) + if not hps or hps == "" then -- if script does not exist or is blank restore from backup + sys.call("cp -f " .. scriptBackup .. " " .. script) + return fs.readfile(script) + else + return hps + end + end + + function t.write(self, section, data) -- format and write new data to script + return fs.writefile(script, ut.trim(data:gsub("\r\n", "\n")) .. "\n") + end + + +return m5 diff --git a/applications/luci-app-mwan3/luasrc/model/cbi/mwan/advanced_mwanconfig.lua b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/advanced_mwanconfig.lua new file mode 100644 index 0000000000..e0a99e8366 --- /dev/null +++ b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/advanced_mwanconfig.lua @@ -0,0 +1,32 @@ +-- ------ mwan configuration ------ -- + +ut = require "luci.util" + +mwanConfig = "/etc/config/mwan3" + + +m5 = SimpleForm("luci", nil) + m5:append(Template("mwan/advanced_mwanconfig")) -- highlight current tab + + +f = m5:section(SimpleSection, nil, + translate("This section allows you to modify the contents of /etc/config/mwan3")) + +t = f:option(TextValue, "lines") + t.rmempty = true + t.rows = 20 + + function t.cfgvalue() + return nixio.fs.readfile(mwanConfig) or "" + end + + function t.write(self, section, data) -- format and write new data to script + return nixio.fs.writefile(mwanConfig, "\n" .. ut.trim(data:gsub("\r\n", "\n")) .. "\n") + end + + function f.handle(self, state, data) + return true + end + + +return m5 diff --git a/applications/luci-app-mwan3/luasrc/model/cbi/mwan/advanced_networkconfig.lua b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/advanced_networkconfig.lua new file mode 100644 index 0000000000..b93d89751b --- /dev/null +++ b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/advanced_networkconfig.lua @@ -0,0 +1,32 @@ +-- ------ network configuration ------ -- + +ut = require "luci.util" + +networkConfig = "/etc/config/network" + + +m5 = SimpleForm("networkconf", nil) + m5:append(Template("mwan/advanced_networkconfig")) -- highlight current tab + + +f = m5:section(SimpleSection, nil, + translate("This section allows you to modify the contents of /etc/config/network")) + +t = f:option(TextValue, "lines") + t.rmempty = true + t.rows = 20 + + function t.cfgvalue() + return nixio.fs.readfile(networkConfig) or "" + end + + function t.write(self, section, data) -- format and write new data to script + return nixio.fs.writefile(networkConfig, "\n" .. ut.trim(data:gsub("\r\n", "\n")) .. "\n") + end + + function f.handle(self, state, data) + return true + end + + +return m5 diff --git a/applications/luci-app-mwan3/luasrc/model/cbi/mwan/advanced_wirelessconfig.lua b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/advanced_wirelessconfig.lua new file mode 100644 index 0000000000..95e9f7c7e5 --- /dev/null +++ b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/advanced_wirelessconfig.lua @@ -0,0 +1,32 @@ +-- ------ wireless configuration ------ -- + +ut = require "luci.util" + +wirelessConfig = "/etc/config/wireless" + + +m5 = SimpleForm("wirelessconf", nil) + m5:append(Template("mwan/advanced_wirelessconfig")) -- highlight current tab + + +f = m5:section(SimpleSection, nil, + translate("This section allows you to modify the contents of /etc/config/wireless")) + +t = f:option(TextValue, "lines") + t.rmempty = true + t.rows = 20 + + function t.cfgvalue() + return nixio.fs.readfile(wirelessConfig) or "" + end + + function t.write(self, section, data) -- format and write new data to script + return nixio.fs.writefile(wirelessConfig, "\n" .. ut.trim(data:gsub("\r\n", "\n")) .. "\n") + end + + function f.handle(self, state, data) + return true + end + + +return m5 diff --git a/applications/luci-app-mwan3/luasrc/model/cbi/mwan/interface.lua b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/interface.lua new file mode 100644 index 0000000000..a8e68a01be --- /dev/null +++ b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/interface.lua @@ -0,0 +1,266 @@ +-- ------ extra functions ------ -- + +function interfaceCheck() -- find issues with too many interfaces, reliability and metric + uci.cursor():foreach("mwan3", "interface", + function (section) + local interfaceName = section[".name"] + interfaceNumber = interfaceNumber+1 -- count number of mwan interfaces configured + -- create list of metrics for none and duplicate checking + local metricValue = ut.trim(sys.exec("uci -p /var/state get network." .. interfaceName .. ".metric")) + if metricValue == "" then + errorFound = 1 + errorNoMetricList = errorNoMetricList .. interfaceName .. " " + else + metricList = metricList .. interfaceName .. " " .. metricValue .. "\n" + end + -- check if any interfaces have a higher reliability requirement than tracking IPs configured + local trackingNumber = tonumber(ut.trim(sys.exec("echo $(uci -p /var/state get mwan3." .. interfaceName .. ".track_ip) | wc -w"))) + if trackingNumber > 0 then + local reliabilityNumber = tonumber(ut.trim(sys.exec("uci -p /var/state get mwan3." .. interfaceName .. ".reliability"))) + if reliabilityNumber and reliabilityNumber > trackingNumber then + errorFound = 1 + errorReliabilityList = errorReliabilityList .. interfaceName .. " " + end + end + -- check if any interfaces are not properly configured in /etc/config/network or have no default route in main routing table + if ut.trim(sys.exec("uci -p /var/state get network." .. interfaceName)) == "interface" then + local interfaceDevice = ut.trim(sys.exec("uci -p /var/state get network." .. interfaceName .. ".ifname")) + if interfaceDevice == "uci: Entry not found" or interfaceDevice == "" then + errorFound = 1 + errorNetConfigList = errorNetConfigList .. interfaceName .. " " + errorRouteList = errorRouteList .. interfaceName .. " " + else + local routeCheck = ut.trim(sys.exec("route -n | awk '{if ($8 == \"" .. interfaceDevice .. "\" && $1 == \"0.0.0.0\" && $3 == \"0.0.0.0\") print $1}'")) + if routeCheck == "" then + errorFound = 1 + errorRouteList = errorRouteList .. interfaceName .. " " + end + end + else + errorFound = 1 + errorNetConfigList = errorNetConfigList .. interfaceName .. " " + errorRouteList = errorRouteList .. interfaceName .. " " + end + end + ) + -- check if any interfaces have duplicate metrics + local metricDuplicateNumbers = sys.exec("echo '" .. metricList .. "' | awk '{print $2}' | uniq -d") + if metricDuplicateNumbers ~= "" then + errorFound = 1 + local metricDuplicates = "" + for line in metricDuplicateNumbers:gmatch("[^\r\n]+") do + metricDuplicates = sys.exec("echo '" .. metricList .. "' | grep '" .. line .. "' | awk '{print $1}'") + errorDuplicateMetricList = errorDuplicateMetricList .. metricDuplicates + end + errorDuplicateMetricList = sys.exec("echo '" .. errorDuplicateMetricList .. "' | tr '\n' ' '") + end +end + +function interfaceWarnings() -- display status and warning messages at the top of the page + local warnings = "" + if interfaceNumber <= 250 then + warnings = "<strong>There are currently " .. interfaceNumber .. " of 250 supported interfaces configured</strong>" + else + warnings = "<font color=\"ff0000\"><strong>WARNING: " .. interfaceNumber .. " interfaces are configured exceeding the maximum of 250!</strong></font>" + end + if errorReliabilityList ~= " " then + warnings = warnings .. "<br /><br /><font color=\"ff0000\"><strong>WARNING: some interfaces have a higher reliability requirement than there are tracking IP addresses!</strong></font>" + end + if errorRouteList ~= " " then + warnings = warnings .. "<br /><br /><font color=\"ff0000\"><strong>WARNING: some interfaces have no default route in the main routing table!</strong></font>" + end + if errorNetConfigList ~= " " then + warnings = warnings .. "<br /><br /><font color=\"ff0000\"><strong>WARNING: some interfaces are configured incorrectly or not at all in /etc/config/network!</strong></font>" + end + if errorNoMetricList ~= " " then + warnings = warnings .. "<br /><br /><font color=\"ff0000\"><strong>WARNING: some interfaces have no metric configured in /etc/config/network!</strong></font>" + end + if errorDuplicateMetricList ~= " " then + warnings = warnings .. "<br /><br /><font color=\"ff0000\"><strong>WARNING: some interfaces have duplicate metrics configured in /etc/config/network!</strong></font>" + end + return warnings +end + +-- ------ interface configuration ------ -- + +dsp = require "luci.dispatcher" +sys = require "luci.sys" +ut = require "luci.util" + +interfaceNumber = 0 +metricList = "" +errorFound = 0 +errorDuplicateMetricList = " " +errorNetConfigList = " " +errorNoMetricList = " " +errorReliabilityList = " " +errorRouteList = " " +interfaceCheck() + + +m5 = Map("mwan3", translate("MWAN Interface Configuration"), + translate(interfaceWarnings())) + m5:append(Template("mwan/config_css")) + + +mwan_interface = m5:section(TypedSection, "interface", translate("Interfaces"), + translate("MWAN supports up to 250 physical and/or logical interfaces<br />" .. + "MWAN requires that all interfaces have a unique metric configured in /etc/config/network<br />" .. + "Names must match the interface name found in /etc/config/network (see advanced tab)<br />" .. + "Names may contain characters A-Z, a-z, 0-9, _ and no spaces<br />" .. + "Interfaces may not share the same name as configured members, policies or rules")) + mwan_interface.addremove = true + mwan_interface.dynamic = false + mwan_interface.sectionhead = "Interface" + mwan_interface.sortable = true + mwan_interface.template = "cbi/tblsection" + mwan_interface.extedit = dsp.build_url("admin", "network", "mwan", "configuration", "interface", "%s") + function mwan_interface.create(self, section) + TypedSection.create(self, section) + m5.uci:save("mwan3") + luci.http.redirect(dsp.build_url("admin", "network", "mwan", "configuration", "interface", section)) + end + + +enabled = mwan_interface:option(DummyValue, "enabled", translate("Enabled")) + enabled.rawhtml = true + function enabled.cfgvalue(self, s) + if self.map:get(s, "enabled") == "1" then + return "Yes" + else + return "No" + end + end + +track_ip = mwan_interface:option(DummyValue, "track_ip", translate("Tracking IP")) + track_ip.rawhtml = true + function track_ip.cfgvalue(self, s) + tracked = self.map:get(s, "track_ip") + if tracked then + local ipList = "" + for k,v in pairs(tracked) do + ipList = ipList .. v .. "<br />" + end + return ipList + else + return "—" + end + end + +reliability = mwan_interface:option(DummyValue, "reliability", translate("Tracking reliability")) + reliability.rawhtml = true + function reliability.cfgvalue(self, s) + if tracked then + return self.map:get(s, "reliability") or "—" + else + return "—" + end + end + +count = mwan_interface:option(DummyValue, "count", translate("Ping count")) + count.rawhtml = true + function count.cfgvalue(self, s) + if tracked then + return self.map:get(s, "count") or "—" + else + return "—" + end + end + +timeout = mwan_interface:option(DummyValue, "timeout", translate("Ping timeout")) + timeout.rawhtml = true + function timeout.cfgvalue(self, s) + if tracked then + local timeoutValue = self.map:get(s, "timeout") + if timeoutValue then + return timeoutValue .. "s" + else + return "—" + end + else + return "—" + end + end + +interval = mwan_interface:option(DummyValue, "interval", translate("Ping interval")) + interval.rawhtml = true + function interval.cfgvalue(self, s) + if tracked then + local intervalValue = self.map:get(s, "interval") + if intervalValue then + return intervalValue .. "s" + else + return "—" + end + else + return "—" + end + end + +down = mwan_interface:option(DummyValue, "down", translate("Interface down")) + down.rawhtml = true + function down.cfgvalue(self, s) + if tracked then + return self.map:get(s, "down") or "—" + else + return "—" + end + end + +up = mwan_interface:option(DummyValue, "up", translate("Interface up")) + up.rawhtml = true + function up.cfgvalue(self, s) + if tracked then + return self.map:get(s, "up") or "—" + else + return "—" + end + end + +metric = mwan_interface:option(DummyValue, "metric", translate("Metric")) + metric.rawhtml = true + function metric.cfgvalue(self, s) + local metricValue = sys.exec("uci -p /var/state get network." .. s .. ".metric") + if metricValue ~= "" then + return metricValue + else + return "—" + end + end + +errors = mwan_interface:option(DummyValue, "errors", translate("Errors")) + errors.rawhtml = true + function errors.cfgvalue(self, s) + if errorFound == 1 then + local mouseOver, lineBreak = "", "" + if string.find(errorReliabilityList, " " .. s .. " ") then + mouseOver = "Higher reliability requirement than there are tracking IP addresses" + lineBreak = " " + end + if string.find(errorRouteList, " " .. s .. " ") then + mouseOver = mouseOver .. lineBreak .. "No default route in the main routing table" + lineBreak = " " + end + if string.find(errorNetConfigList, " " .. s .. " ") then + mouseOver = mouseOver .. lineBreak .. "Configured incorrectly or not at all in /etc/config/network" + lineBreak = " " + end + if string.find(errorNoMetricList, " " .. s .. " ") then + mouseOver = mouseOver .. lineBreak .. "No metric configured in /etc/config/network" + lineBreak = " " + end + if string.find(errorDuplicateMetricList, " " .. s .. " ") then + mouseOver = mouseOver .. lineBreak .. "Duplicate metric configured in /etc/config/network" + end + if mouseOver == "" then + return "" + else + return "<span title=\"" .. mouseOver .. "\"><img src=\"/luci-static/resources/cbi/reset.gif\" alt=\"error\"></img></span>" + end + else + return "" + end + end + + +return m5 diff --git a/applications/luci-app-mwan3/luasrc/model/cbi/mwan/interfaceconfig.lua b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/interfaceconfig.lua new file mode 100644 index 0000000000..387ff01a8d --- /dev/null +++ b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/interfaceconfig.lua @@ -0,0 +1,190 @@ +-- ------ extra functions ------ -- + +function interfaceCheck() + metricValue = ut.trim(sys.exec("uci -p /var/state get network." .. arg[1] .. ".metric")) + if metricValue == "" then -- no metric + errorNoMetric = 1 + else -- if metric exists create list of interface metrics to compare against for duplicates + uci.cursor():foreach("mwan3", "interface", + function (section) + local metricValue = ut.trim(sys.exec("uci -p /var/state get network." .. section[".name"] .. ".metric")) + metricList = metricList .. section[".name"] .. " " .. metricValue .. "\n" + end + ) + -- compare metric against list + local metricDuplicateNumbers, metricDuplicates = sys.exec("echo '" .. metricList .. "' | awk '{print $2}' | uniq -d"), "" + for line in metricDuplicateNumbers:gmatch("[^\r\n]+") do + metricDuplicates = sys.exec("echo '" .. metricList .. "' | grep '" .. line .. "' | awk '{print $1}'") + errorDuplicateMetricList = errorDuplicateMetricList .. metricDuplicates + end + if sys.exec("echo '" .. errorDuplicateMetricList .. "' | grep -w " .. arg[1]) ~= "" then + errorDuplicateMetric = 1 + end + end + -- check if this interface has a higher reliability requirement than track IPs configured + local trackingNumber = tonumber(ut.trim(sys.exec("echo $(uci -p /var/state get mwan3." .. arg[1] .. ".track_ip) | wc -w"))) + if trackingNumber > 0 then + local reliabilityNumber = tonumber(ut.trim(sys.exec("uci -p /var/state get mwan3." .. arg[1] .. ".reliability"))) + if reliabilityNumber and reliabilityNumber > trackingNumber then + errorReliability = 1 + end + end + -- check if any interfaces are not properly configured in /etc/config/network or have no default route in main routing table + if ut.trim(sys.exec("uci -p /var/state get network." .. arg[1])) == "interface" then + local interfaceDevice = ut.trim(sys.exec("uci -p /var/state get network." .. arg[1] .. ".ifname")) + if interfaceDevice == "uci: Entry not found" or interfaceDevice == "" then + errorNetConfig = 1 + errorRoute = 1 + else + local routeCheck = ut.trim(sys.exec("route -n | awk '{if ($8 == \"" .. interfaceDevice .. "\" && $1 == \"0.0.0.0\" && $3 == \"0.0.0.0\") print $1}'")) + if routeCheck == "" then + errorRoute = 1 + end + end + else + errorNetConfig = 1 + errorRoute = 1 + end +end + +function interfaceWarnings() -- display warning messages at the top of the page + local warns, lineBreak = "", "" + if errorReliability == 1 then + warns = "<font color=\"ff0000\"><strong>WARNING: this interface has a higher reliability requirement than there are tracking IP addresses!</strong></font>" + lineBreak = "<br /><br />" + end + if errorRoute == 1 then + warns = warns .. lineBreak .. "<font color=\"ff0000\"><strong>WARNING: this interface has no default route in the main routing table!</strong></font>" + lineBreak = "<br /><br />" + end + if errorNetConfig == 1 then + warns = warns .. lineBreak .. "<font color=\"ff0000\"><strong>WARNING: this interface is configured incorrectly or not at all in /etc/config/network!</strong></font>" + lineBreak = "<br /><br />" + end + if errorNoMetric == 1 then + warns = warns .. lineBreak .. "<font color=\"ff0000\"><strong>WARNING: this interface has no metric configured in /etc/config/network!</strong></font>" + elseif errorDuplicateMetric == 1 then + warns = warns .. lineBreak .. "<font color=\"ff0000\"><strong>WARNING: this and other interfaces have duplicate metrics configured in /etc/config/network!</strong></font>" + end + return warns +end + +-- ------ interface configuration ------ -- + +dsp = require "luci.dispatcher" +sys = require "luci.sys" +ut = require "luci.util" +arg[1] = arg[1] or "" + +metricValue = "" +metricList = "" +errorDuplicateMetricList = "" +errorNoMetric = 0 +errorDuplicateMetric = 0 +errorRoute = 0 +errorNetConfig = 0 +errorReliability = 0 +interfaceCheck() + + +m5 = Map("mwan3", translate("MWAN Interface Configuration - " .. arg[1]), + translate(interfaceWarnings())) + m5.redirect = dsp.build_url("admin", "network", "mwan", "configuration", "interface") + + +mwan_interface = m5:section(NamedSection, arg[1], "interface", "") + mwan_interface.addremove = false + mwan_interface.dynamic = false + + +enabled = mwan_interface:option(ListValue, "enabled", translate("Enabled")) + enabled.default = "1" + enabled:value("1", translate("Yes")) + enabled:value("0", translate("No")) + +track_ip = mwan_interface:option(DynamicList, "track_ip", translate("Tracking IP"), + translate("This IP address will be pinged to dermine if the link is up or down. Leave blank to assume interface is always online")) + track_ip.datatype = "ipaddr" + +reliability = mwan_interface:option(Value, "reliability", translate("Tracking reliability"), + translate("Acceptable values: 1-100. This many Tracking IP addresses must respond for the link to be deemed up")) + reliability.datatype = "range(1, 100)" + reliability.default = "1" + +count = mwan_interface:option(ListValue, "count", translate("Ping count")) + count.default = "1" + count:value("1") + count:value("2") + count:value("3") + count:value("4") + count:value("5") + +timeout = mwan_interface:option(ListValue, "timeout", translate("Ping timeout")) + timeout.default = "2" + timeout:value("1", translate("1 second")) + timeout:value("2", translate("2 seconds")) + timeout:value("3", translate("3 seconds")) + timeout:value("4", translate("4 seconds")) + timeout:value("5", translate("5 seconds")) + timeout:value("6", translate("6 seconds")) + timeout:value("7", translate("7 seconds")) + timeout:value("8", translate("8 seconds")) + timeout:value("9", translate("9 seconds")) + timeout:value("10", translate("10 seconds")) + +interval = mwan_interface:option(ListValue, "interval", translate("Ping interval")) + interval.default = "5" + interval:value("1", translate("1 second")) + interval:value("3", translate("3 seconds")) + interval:value("5", translate("5 seconds")) + interval:value("10", translate("10 seconds")) + interval:value("20", translate("20 seconds")) + interval:value("30", translate("30 seconds")) + interval:value("60", translate("1 minute")) + interval:value("300", translate("5 minutes")) + interval:value("600", translate("10 minutes")) + interval:value("900", translate("15 minutes")) + interval:value("1800", translate("30 minutes")) + interval:value("3600", translate("1 hour")) + +down = mwan_interface:option(ListValue, "down", translate("Interface down"), + translate("Interface will be deemed down after this many failed ping tests")) + down.default = "3" + down:value("1") + down:value("2") + down:value("3") + down:value("4") + down:value("5") + down:value("6") + down:value("7") + down:value("8") + down:value("9") + down:value("10") + +up = mwan_interface:option(ListValue, "up", translate("Interface up"), + translate("Downed interface will be deemed up after this many successful ping tests")) + up.default = "3" + up:value("1") + up:value("2") + up:value("3") + up:value("4") + up:value("5") + up:value("6") + up:value("7") + up:value("8") + up:value("9") + up:value("10") + +metric = mwan_interface:option(DummyValue, "metric", translate("Metric"), + translate("This displays the metric assigned to this interface in /etc/config/network")) + metric.rawhtml = true + function metric.cfgvalue(self, s) + if errorNoMetric == 0 then + return metricValue + else + return "—" + end + end + + +return m5 diff --git a/applications/luci-app-mwan3/luasrc/model/cbi/mwan/member.lua b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/member.lua new file mode 100644 index 0000000000..3bccbd942f --- /dev/null +++ b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/member.lua @@ -0,0 +1,46 @@ +-- ------ member configuration ------ -- + +ds = require "luci.dispatcher" + + +m5 = Map("mwan3", translate("MWAN Member Configuration")) + m5:append(Template("mwan/config_css")) + + +mwan_member = m5:section(TypedSection, "member", translate("Members"), + translate("Members are profiles attaching a metric and weight to an MWAN interface<br />" .. + "Names may contain characters A-Z, a-z, 0-9, _ and no spaces<br />" .. + "Members may not share the same name as configured interfaces, policies or rules")) + mwan_member.addremove = true + mwan_member.dynamic = false + mwan_member.sectionhead = "Member" + mwan_member.sortable = true + mwan_member.template = "cbi/tblsection" + mwan_member.extedit = ds.build_url("admin", "network", "mwan", "configuration", "member", "%s") + function mwan_member.create(self, section) + TypedSection.create(self, section) + m5.uci:save("mwan3") + luci.http.redirect(ds.build_url("admin", "network", "mwan", "configuration", "member", section)) + end + + +interface = mwan_member:option(DummyValue, "interface", translate("Interface")) + interface.rawhtml = true + function interface.cfgvalue(self, s) + return self.map:get(s, "interface") or "—" + end + +metric = mwan_member:option(DummyValue, "metric", translate("Metric")) + metric.rawhtml = true + function metric.cfgvalue(self, s) + return self.map:get(s, "metric") or "1" + end + +weight = mwan_member:option(DummyValue, "weight", translate("Weight")) + weight.rawhtml = true + function weight.cfgvalue(self, s) + return self.map:get(s, "weight") or "1" + end + + +return m5 diff --git a/applications/luci-app-mwan3/luasrc/model/cbi/mwan/memberconfig.lua b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/memberconfig.lua new file mode 100644 index 0000000000..181d22e06f --- /dev/null +++ b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/memberconfig.lua @@ -0,0 +1,47 @@ +-- ------ extra functions ------ -- + +function cbi_add_interface(field) + uci.cursor():foreach("mwan3", "interface", + function (section) + field:value(section[".name"]) + end + ) +end + +-- ------ member configuration ------ -- + +dsp = require "luci.dispatcher" +arg[1] = arg[1] or "" + + +m5 = Map("mwan3", translate("MWAN Member Configuration - ") .. arg[1]) + m5.redirect = dsp.build_url("admin", "network", "mwan", "configuration", "member") + + +mwan_member = m5:section(NamedSection, arg[1], "member", "") + mwan_member.addremove = false + mwan_member.dynamic = false + + +interface = mwan_member:option(Value, "interface", translate("Interface")) + cbi_add_interface(interface) + +metric = mwan_member:option(Value, "metric", translate("Metric"), + translate("Acceptable values: 1-1000. Defaults to 1 if not set")) + metric.datatype = "range(1, 1000)" + +weight = mwan_member:option(Value, "weight", translate("Weight"), + translate("Acceptable values: 1-1000. Defaults to 1 if not set")) + weight.datatype = "range(1, 1000)" + + +-- ------ currently configured interfaces ------ -- + +mwan_interface = m5:section(TypedSection, "interface", translate("Currently Configured Interfaces")) + mwan_interface.addremove = false + mwan_interface.dynamic = false + mwan_interface.sortable = false + mwan_interface.template = "cbi/tblsection" + + +return m5 diff --git a/applications/luci-app-mwan3/luasrc/model/cbi/mwan/policy.lua b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/policy.lua new file mode 100644 index 0000000000..e141d696a9 --- /dev/null +++ b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/policy.lua @@ -0,0 +1,95 @@ +-- ------ extra functions ------ -- + +function policyCheck() -- check to see if any policy names exceed the maximum of 15 characters + uci.cursor():foreach("mwan3", "policy", + function (section) + if string.len(section[".name"]) > 15 then + nameTooLong = 1 + err_name_list = err_name_list .. section[".name"] .. " " + end + end + ) +end + +function policyWarn() -- display status and warning messages at the top of the page + if nameTooLong == 1 then + return "<font color=\"ff0000\"><strong>WARNING: Some policies have names exceeding the maximum of 15 characters!</strong></font>" + else + return "" + end +end + +-- ------ policy configuration ------ -- + +ds = require "luci.dispatcher" +sys = require "luci.sys" + +nameTooLong = 0 +err_name_list = " " +policyCheck() + + +m5 = Map("mwan3", translate("MWAN Policy Configuration"), + translate(policyWarn())) + m5:append(Template("mwan/config_css")) + + +mwan_policy = m5:section(TypedSection, "policy", translate("Policies"), + translate("Policies are profiles grouping one or more members controlling how MWAN distributes traffic<br />" .. + "Member interfaces with lower metrics are used first. Interfaces with the same metric load-balance<br />" .. + "Load-balanced member interfaces distribute more traffic out those with higher weights<br />" .. + "Names may contain characters A-Z, a-z, 0-9, _ and no spaces. Names must be 15 characters or less<br />" .. + "Policies may not share the same name as configured interfaces, members or rules")) + mwan_policy.addremove = true + mwan_policy.dynamic = false + mwan_policy.sectionhead = "Policy" + mwan_policy.sortable = true + mwan_policy.template = "cbi/tblsection" + mwan_policy.extedit = ds.build_url("admin", "network", "mwan", "configuration", "policy", "%s") + function mwan_policy.create(self, section) + TypedSection.create(self, section) + m5.uci:save("mwan3") + luci.http.redirect(ds.build_url("admin", "network", "mwan", "configuration", "policy", section)) + end + + +use_member = mwan_policy:option(DummyValue, "use_member", translate("Members assigned")) + use_member.rawhtml = true + function use_member.cfgvalue(self, s) + local memberConfig, memberList = self.map:get(s, "use_member"), "" + if memberConfig then + for k,v in pairs(memberConfig) do + memberList = memberList .. v .. "<br />" + end + return memberList + else + return "—" + end + + end + +last_resort = mwan_policy:option(DummyValue, "last_resort", translate("Last resort")) + last_resort.rawhtml = true + function last_resort.cfgvalue(self, s) + local action = self.map:get(s, "last_resort") + if action == "blackhole" then + return "blackhole (drop)" + elseif action == "default" then + return "default (use main routing table)" + else + return "unreachable (reject)" + end + end + +errors = mwan_policy:option(DummyValue, "errors", translate("Errors")) + errors.rawhtml = true + function errors.cfgvalue(self, s) + if not string.find(err_name_list, " " .. s .. " ") then + return "" + else + return "<span title=\"Name exceeds 15 characters\"><img src=\"/luci-static/resources/cbi/reset.gif\" alt=\"error\"></img></span>" + end + end + + +return m5 diff --git a/applications/luci-app-mwan3/luasrc/model/cbi/mwan/policyconfig.lua b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/policyconfig.lua new file mode 100644 index 0000000000..f48a104c67 --- /dev/null +++ b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/policyconfig.lua @@ -0,0 +1,65 @@ +-- ------ extra functions ------ -- + +function policyCheck() -- check to see if this policy's name exceed the maximum of 15 characters + policyNameLength = string.len(arg[1]) + if policyNameLength > 15 then + nameTooLong = 1 + end +end + +function policyWarn() -- display status and warning messages at the top of the page + if nameTooLong == 1 then + return "<font color=\"ff0000\"><strong>WARNING: this policy's name is " .. policyNameLength .. " characters exceeding the maximum of 15!</strong></font>" + else + return "" + end +end + +function cbiAddMember(field) + uci.cursor():foreach("mwan3", "member", + function (section) + field:value(section[".name"]) + end + ) +end + +-- ------ policy configuration ------ -- + +dsp = require "luci.dispatcher" +arg[1] = arg[1] or "" + +nameTooLong = 0 +policyCheck() + + +m5 = Map("mwan3", translate("MWAN Policy Configuration - " .. arg[1]), + translate(policyWarn())) + m5.redirect = dsp.build_url("admin", "network", "mwan", "configuration", "policy") + + +mwan_policy = m5:section(NamedSection, arg[1], "policy", "") + mwan_policy.addremove = false + mwan_policy.dynamic = false + + +use_member = mwan_policy:option(DynamicList, "use_member", translate("Member used")) + cbiAddMember(use_member) + +last_resort = mwan_policy:option(ListValue, "last_resort", translate("Last resort"), + translate("When all policy members are offline use this behavior for matched traffic")) + last_resort.default = "unreachable" + last_resort:value("unreachable", translate("unreachable (reject)")) + last_resort:value("blackhole", translate("blackhole (drop)")) + last_resort:value("default", translate("default (use main routing table)")) + + +-- ------ currently configured members ------ -- + +mwan_member = m5:section(TypedSection, "member", translate("Currently Configured Members")) + mwan_member.addremove = false + mwan_member.dynamic = false + mwan_member.sortable = false + mwan_member.template = "cbi/tblsection" + + +return m5 diff --git a/applications/luci-app-mwan3/luasrc/model/cbi/mwan/rule.lua b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/rule.lua new file mode 100644 index 0000000000..a22e01054c --- /dev/null +++ b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/rule.lua @@ -0,0 +1,141 @@ +-- ------ extra functions ------ -- + +function ruleCheck() -- determine if rules needs a proper protocol configured + uci.cursor():foreach("mwan3", "rule", + function (section) + local sourcePort = ut.trim(sys.exec("uci -p /var/state get mwan3." .. section[".name"] .. ".src_port")) + local destPort = ut.trim(sys.exec("uci -p /var/state get mwan3." .. section[".name"] .. ".dest_port")) + if sourcePort ~= "" or destPort ~= "" then -- ports configured + local protocol = ut.trim(sys.exec("uci -p /var/state get mwan3." .. section[".name"] .. ".proto")) + if protocol == "" or protocol == "all" then -- no or improper protocol + error_protocol_list = error_protocol_list .. section[".name"] .. " " + end + end + end + ) +end + +function ruleWarn() -- display warning messages at the top of the page + if error_protocol_list ~= " " then + return "<font color=\"ff0000\"><strong>WARNING: some rules have a port configured with no or improper protocol specified! Please configure a specific protocol!</strong></font>" + else + return "" + end +end + +-- ------ rule configuration ------ -- + +dsp = require "luci.dispatcher" +sys = require "luci.sys" +ut = require "luci.util" + +error_protocol_list = " " +ruleCheck() + + +m5 = Map("mwan3", translate("MWAN Rule Configuration"), + translate(ruleWarn())) + m5:append(Template("mwan/config_css")) + + +mwan_rule = m5:section(TypedSection, "rule", translate("Traffic Rules"), + translate("Rules specify which traffic will use a particular MWAN policy based on IP address, port or protocol<br />" .. + "Rules are matched from top to bottom. Rules below a matching rule are ignored. Traffic not matching any rule is routed using the main routing table<br />" .. + "Traffic destined for known (other than default) networks is handled by the main routing table. Traffic matching a rule, but all WAN interfaces for that policy are down will be blackholed<br />" .. + "Names may contain characters A-Z, a-z, 0-9, _ and no spaces<br />" .. + "Rules may not share the same name as configured interfaces, members or policies")) + mwan_rule.addremove = true + mwan_rule.anonymous = false + mwan_rule.dynamic = false + mwan_rule.sectionhead = "Rule" + mwan_rule.sortable = true + mwan_rule.template = "cbi/tblsection" + mwan_rule.extedit = dsp.build_url("admin", "network", "mwan", "configuration", "rule", "%s") + function mwan_rule.create(self, section) + TypedSection.create(self, section) + m5.uci:save("mwan3") + luci.http.redirect(dsp.build_url("admin", "network", "mwan", "configuration", "rule", section)) + end + + +src_ip = mwan_rule:option(DummyValue, "src_ip", translate("Source address")) + src_ip.rawhtml = true + function src_ip.cfgvalue(self, s) + return self.map:get(s, "src_ip") or "—" + end + +src_port = mwan_rule:option(DummyValue, "src_port", translate("Source port")) + src_port.rawhtml = true + function src_port.cfgvalue(self, s) + return self.map:get(s, "src_port") or "—" + end + +dest_ip = mwan_rule:option(DummyValue, "dest_ip", translate("Destination address")) + dest_ip.rawhtml = true + function dest_ip.cfgvalue(self, s) + return self.map:get(s, "dest_ip") or "—" + end + +dest_port = mwan_rule:option(DummyValue, "dest_port", translate("Destination port")) + dest_port.rawhtml = true + function dest_port.cfgvalue(self, s) + return self.map:get(s, "dest_port") or "—" + end + +proto = mwan_rule:option(DummyValue, "proto", translate("Protocol")) + proto.rawhtml = true + function proto.cfgvalue(self, s) + return self.map:get(s, "proto") or "all" + end + +sticky = mwan_rule:option(DummyValue, "sticky", translate("Sticky")) + sticky.rawhtml = true + function sticky.cfgvalue(self, s) + if self.map:get(s, "sticky") == "1" then + stickied = 1 + return "Yes" + else + stickied = nil + return "No" + end + end + +timeout = mwan_rule:option(DummyValue, "timeout", translate("Sticky timeout")) + timeout.rawhtml = true + function timeout.cfgvalue(self, s) + if stickied then + local timeoutValue = self.map:get(s, "timeout") + if timeoutValue then + return timeoutValue .. "s" + else + return "600s" + end + else + return "—" + end + end + +ipset = mwan_rule:option(DummyValue, "ipset", translate("IPset")) + ipset.rawhtml = true + function ipset.cfgvalue(self, s) + return self.map:get(s, "ipset") or "—" + end + +use_policy = mwan_rule:option(DummyValue, "use_policy", translate("Policy assigned")) + use_policy.rawhtml = true + function use_policy.cfgvalue(self, s) + return self.map:get(s, "use_policy") or "—" + end + +errors = mwan_rule:option(DummyValue, "errors", translate("Errors")) + errors.rawhtml = true + function errors.cfgvalue(self, s) + if not string.find(error_protocol_list, " " .. s .. " ") then + return "" + else + return "<span title=\"No protocol specified\"><img src=\"/luci-static/resources/cbi/reset.gif\" alt=\"error\"></img></span>" + end + end + + +return m5 diff --git a/applications/luci-app-mwan3/luasrc/model/cbi/mwan/ruleconfig.lua b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/ruleconfig.lua new file mode 100644 index 0000000000..f7fb341e1f --- /dev/null +++ b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/ruleconfig.lua @@ -0,0 +1,113 @@ +-- ------ extra functions ------ -- + +function ruleCheck() -- determine if rule needs a protocol specified + local sourcePort = ut.trim(sys.exec("uci -p /var/state get mwan3." .. arg[1] .. ".src_port")) + local destPort = ut.trim(sys.exec("uci -p /var/state get mwan3." .. arg[1] .. ".dest_port")) + if sourcePort ~= "" or destPort ~= "" then -- ports configured + local protocol = ut.trim(sys.exec("uci -p /var/state get mwan3." .. arg[1] .. ".proto")) + if protocol == "" or protocol == "all" then -- no or improper protocol + error_protocol = 1 + end + end +end + +function ruleWarn() -- display warning message at the top of the page + if error_protocol == 1 then + return "<font color=\"ff0000\"><strong>WARNING: this rule is incorrectly configured with no or improper protocol specified! Please configure a specific protocol!</strong></font>" + else + return "" + end +end + +function cbiAddPolicy(field) + uci.cursor():foreach("mwan3", "policy", + function (section) + field:value(section[".name"]) + end + ) +end + +function cbiAddProtocol(field) + local protocols = ut.trim(sys.exec("cat /etc/protocols | grep ' # ' | awk '{print $1}' | grep -vw -e 'ip' -e 'tcp' -e 'udp' -e 'icmp' -e 'esp' | grep -v 'ipv6' | sort | tr '\n' ' '")) + for p in string.gmatch(protocols, "%S+") do + field:value(p) + end +end + +-- ------ rule configuration ------ -- + +dsp = require "luci.dispatcher" +sys = require "luci.sys" +ut = require "luci.util" +arg[1] = arg[1] or "" + +error_protocol = 0 +ruleCheck() + + +m5 = Map("mwan3", translate("MWAN Rule Configuration - ") .. arg[1], + translate(ruleWarn())) + m5.redirect = dsp.build_url("admin", "network", "mwan", "configuration", "rule") + + +mwan_rule = m5:section(NamedSection, arg[1], "rule", "") + mwan_rule.addremove = false + mwan_rule.dynamic = false + + +src_ip = mwan_rule:option(Value, "src_ip", translate("Source address"), + translate("Supports CIDR notation (eg \"192.168.100.0/24\") without quotes")) + src_ip.datatype = ipaddr + +src_port = mwan_rule:option(Value, "src_port", translate("Source port"), + translate("May be entered as a single or multiple port(s) (eg \"22\" or \"80,443\") or as a portrange (eg \"1024:2048\") without quotes")) + +dest_ip = mwan_rule:option(Value, "dest_ip", translate("Destination address"), + translate("Supports CIDR notation (eg \"192.168.100.0/24\") without quotes")) + dest_ip.datatype = ipaddr + +dest_port = mwan_rule:option(Value, "dest_port", translate("Destination port"), + translate("May be entered as a single or multiple port(s) (eg \"22\" or \"80,443\") or as a portrange (eg \"1024:2048\") without quotes")) + +proto = mwan_rule:option(Value, "proto", translate("Protocol"), + translate("View the contents of /etc/protocols for protocol descriptions")) + proto.default = "all" + proto.rmempty = false + proto:value("all") + proto:value("ip") + proto:value("tcp") + proto:value("udp") + proto:value("icmp") + proto:value("esp") + cbiAddProtocol(proto) + +sticky = mwan_rule:option(ListValue, "sticky", translate("Sticky"), + translate("Traffic from the same source IP address that previously matched this rule within the sticky timeout period will use the same WAN interface")) + sticky.default = "0" + sticky:value("1", translate("Yes")) + sticky:value("0", translate("No")) + +timeout = mwan_rule:option(Value, "timeout", translate("Sticky timeout"), + translate("Seconds. Acceptable values: 1-1000000. Defaults to 600 if not set")) + timeout.datatype = "range(1, 1000000)" + +ipset = mwan_rule:option(Value, "ipset", translate("IPset"), + translate("Name of IPset rule. Requires IPset rule in /etc/dnsmasq.conf (eg \"ipset=/youtube.com/youtube\")")) + +use_policy = mwan_rule:option(Value, "use_policy", translate("Policy assigned")) + cbiAddPolicy(use_policy) + use_policy:value("unreachable", translate("unreachable (reject)")) + use_policy:value("blackhole", translate("blackhole (drop)")) + use_policy:value("default", translate("default (use main routing table)")) + + +-- ------ currently configured policies ------ -- + +mwan_policy = m5:section(TypedSection, "policy", translate("Currently Configured Policies")) + mwan_policy.addremove = false + mwan_policy.dynamic = false + mwan_policy.sortable = false + mwan_policy.template = "cbi/tblsection" + + +return m5 diff --git a/applications/luci-app-mwan3/luasrc/view/admin_status/index/mwan.htm b/applications/luci-app-mwan3/luasrc/view/admin_status/index/mwan.htm new file mode 100644 index 0000000000..53b997af90 --- /dev/null +++ b/applications/luci-app-mwan3/luasrc/view/admin_status/index/mwan.htm @@ -0,0 +1 @@ +<%+mwan/openwrt_overview_status%> diff --git a/applications/luci-app-mwan3/luasrc/view/mwan/advanced_diagnostics.htm b/applications/luci-app-mwan3/luasrc/view/mwan/advanced_diagnostics.htm new file mode 100644 index 0000000000..14d404bc7c --- /dev/null +++ b/applications/luci-app-mwan3/luasrc/view/mwan/advanced_diagnostics.htm @@ -0,0 +1,129 @@ +<%+header%> + +<ul class="cbi-tabmenu"> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/hotplugscript")%>"><%:Hotplug Script%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/mwanconfig")%>"><%:MWAN Config%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/networkconfig")%>"><%:Network Config%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/wirelessconfig")%>"><%:Wireless Config%></a></li> + <li class="cbi-tab"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/diagnostics")%>"><%:Diagnostics%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/troubleshooting")%>"><%:Troubleshooting%></a></li> +</ul> + +<% + local uci = require "luci.model.uci" + + interfaceNames = "" + uci.cursor():foreach("mwan3", "interface", + function (section) + interfaceNames = interfaceNames .. section[".name"] .. " " + end + ) +%> + +<script type="text/javascript" src="<%=resource%>/cbi.js"></script> +<script type="text/javascript">//<![CDATA[ + var stxhr = new XHR(); + + function update_status(tool, task) + { + var iface = document.getElementById('mwaniface').value; + var output = document.getElementById('diag_output'); + + if (tool == "service") + { + output.innerHTML = + '<img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="padding: 20px; vertical-align: middle;" /> ' + + "Waiting for MWAN to " + task + "..." + ; + } + else + { + output.innerHTML = + '<img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="padding: 20px; vertical-align: middle;" /> ' + + "Waiting for diagnostic results..." + ; + } + + output.parentNode.style.display = 'block'; + output.style.display = 'inline'; + + stxhr.get('<%=luci.dispatcher.build_url("admin", "network", "mwan", "advanced")%>/diagnostics_display' + '/' + iface + '/' + tool + '/' + task, null, + function(x, mArray) + { + if (mArray.diagnostics) + { + output.innerHTML = String.format('<pre id="diag_output_css">%h</pre>', mArray.diagnostics[0]); + } + else + { + output.innerHTML = '<pre id="diag_output_css"><strong>No diagnostic results returned</strong></pre>'; + } + } + ); + } +//]]></script> + +<div id="mwan_diagnostics" class="cbi-map"> + <fieldset id="diag_select" class="cbi-section"> + <legend><%:MWAN Interface Diagnostics%></legend> + <select id="mwaniface"> + <% for z in interfaceNames:gmatch("[^ ]+") do -%><option value="<%=z%>"><%=z%></option><%- end %> + </select> + <div id="buttoncss"> + <input type="button" value="<%:Ping default gateway%>" class="cbi-button cbi-button-apply" onclick="update_status('ping', 'gateway')" /> + <input type="button" value="<%:Ping tracking IP%>" class="cbi-button cbi-button-apply" onclick="update_status('ping', 'track_ip')" /> + <input type="button" value="<%:Check IP rules%>" class="cbi-button cbi-button-apply" onclick="update_status('rulechk', null)" /> + <input type="button" value="<%:Check routing table%>" class="cbi-button cbi-button-apply" onclick="update_status('routechk', null)" /> + <input type="button" value="<%:Hotplug ifup%>" class="cbi-button cbi-button-apply" onclick="update_status('hotplug', 'ifup')" /> + <input type="button" value="<%:Hotplug ifdown%>" class="cbi-button cbi-button-apply" onclick="update_status('hotplug', 'ifdown')" /> + </div> + </fieldset> + <fieldset id="diag_select" class="cbi-section"> + <legend><%:MWAN Service Control%></legend> + <div id="buttoncss"> + <input type="button" value="<%:Restart MWAN%>" class="cbi-button cbi-button-apply" onclick="update_status('service', 'restart')" /> + <input type="button" value="<%:Stop MWAN%>" class="cbi-button cbi-button-apply" onclick="update_status('service', 'stop')" /> + <input type="button" value="<%:Start MWAN%>" class="cbi-button cbi-button-apply" onclick="update_status('service', 'start')" /> + </div> + </fieldset> + <fieldset class="cbi-section" style="display:none"> + <legend><%:Diagnostic Results%></legend> + <div id="diag_output"></div> + </fieldset> +</div> + +<style type="text/css"> + .container { /* container for entire page. fixes bootstrap theme's ridiculously small page width */ + max-width: none; + margin-left: 30px; + padding-right: 30px; + width: auto; + } + #mwan_diagnostics { + background-color: #FFFFFF; + border: 1px dotted #555555; + padding: 20px; + } + #diag_select { + padding: 12px 20px 20px 20px; + } + #mwaniface { + float: left; + margin: 8px 20px 0px 0px; + } + #buttoncss { + display: table; + float: left; + text-align: left; + } + .cbi-button { + margin: 8px 20px 0px 0px; + min-width: 153px; + } + #diag_output_css { + padding: 20px; + text-align: left; + } +</style> + +<%+footer%> diff --git a/applications/luci-app-mwan3/luasrc/view/mwan/advanced_hotplugscript.htm b/applications/luci-app-mwan3/luasrc/view/mwan/advanced_hotplugscript.htm new file mode 100644 index 0000000000..4c2a0dc208 --- /dev/null +++ b/applications/luci-app-mwan3/luasrc/view/mwan/advanced_hotplugscript.htm @@ -0,0 +1,24 @@ +<ul class="cbi-tabmenu"> + <li class="cbi-tab"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/hotplugscript")%>"><%:Hotplug Script%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/mwanconfig")%>"><%:MWAN Config%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/networkconfig")%>"><%:Network Config%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/wirelessconfig")%>"><%:Wireless Config%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/diagnostics")%>"><%:Diagnostics%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/troubleshooting")%>"><%:Troubleshooting%></a></li> +</ul> + +<style type="text/css"> + .container { /* container for entire page. fixes bootstrap theme's ridiculously small page width */ + max-width: none; + margin: 0px 0px 0px 30px; + padding-right: 30px; + width: auto; + } + .cbi-section-node { + margin-top: 20px; + } + .cbi-section { + border: 1px dotted #555555; + padding: 20px; + } +</style> diff --git a/applications/luci-app-mwan3/luasrc/view/mwan/advanced_mwanconfig.htm b/applications/luci-app-mwan3/luasrc/view/mwan/advanced_mwanconfig.htm new file mode 100644 index 0000000000..fba3fa6940 --- /dev/null +++ b/applications/luci-app-mwan3/luasrc/view/mwan/advanced_mwanconfig.htm @@ -0,0 +1,24 @@ +<ul class="cbi-tabmenu"> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/hotplugscript")%>"><%:Hotplug Script%></a></li> + <li class="cbi-tab"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/mwanconfig")%>"><%:MWAN Config%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/networkconfig")%>"><%:Network Config%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/wirelessconfig")%>"><%:Wireless Config%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/diagnostics")%>"><%:Diagnostics%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/troubleshooting")%>"><%:Troubleshooting%></a></li> +</ul> + +<style type="text/css"> + .container { /* container for entire page. fixes bootstrap theme's ridiculously small page width */ + max-width: none; + margin: 0px 0px 0px 30px; + padding-right: 30px; + width: auto; + } + .cbi-section-node { + margin-top: 20px; + } + .cbi-section { + border: 1px dotted #555555; + padding: 20px; + } +</style> diff --git a/applications/luci-app-mwan3/luasrc/view/mwan/advanced_networkconfig.htm b/applications/luci-app-mwan3/luasrc/view/mwan/advanced_networkconfig.htm new file mode 100644 index 0000000000..cf90112078 --- /dev/null +++ b/applications/luci-app-mwan3/luasrc/view/mwan/advanced_networkconfig.htm @@ -0,0 +1,24 @@ +<ul class="cbi-tabmenu"> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/hotplugscript")%>"><%:Hotplug Script%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/mwanconfig")%>"><%:MWAN Config%></a></li> + <li class="cbi-tab"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/networkconfig")%>"><%:Network Config%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/wirelessconfig")%>"><%:Wireless Config%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/diagnostics")%>"><%:Diagnostics%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/troubleshooting")%>"><%:Troubleshooting%></a></li> +</ul> + +<style type="text/css"> + .container { /* container for entire page. fixes bootstrap theme's ridiculously small page width */ + max-width: none; + margin: 0px 0px 0px 30px; + padding-right: 30px; + width: auto; + } + .cbi-section-node { + margin-top: 20px; + } + .cbi-section { + border: 1px dotted #555555; + padding: 20px; + } +</style> diff --git a/applications/luci-app-mwan3/luasrc/view/mwan/advanced_troubleshooting.htm b/applications/luci-app-mwan3/luasrc/view/mwan/advanced_troubleshooting.htm new file mode 100644 index 0000000000..0a12496899 --- /dev/null +++ b/applications/luci-app-mwan3/luasrc/view/mwan/advanced_troubleshooting.htm @@ -0,0 +1,74 @@ +<%+header%> + +<ul class="cbi-tabmenu"> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/hotplugscript")%>"><%:Hotplug Script%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/mwanconfig")%>"><%:MWAN Config%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/networkconfig")%>"><%:Network Config%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/wirelessconfig")%>"><%:Wireless Config%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/diagnostics")%>"><%:Diagnostics%></a></li> + <li class="cbi-tab"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/troubleshooting")%>"><%:Troubleshooting%></a></li> +</ul> + +<script type="text/javascript" src="<%=resource%>/cbi.js"></script> +<script type="text/javascript">//<![CDATA[ + XHR.poll(15, '<%=luci.dispatcher.build_url("admin", "network", "mwan", "advanced", "troubleshooting_display")%>', null, + function(x, mArray) + { + var tshoot = document.getElementById('troubleshoot_text'); + if (mArray.versions) + { + var versions = '<span class="description">Software versions : </span><br /><br />'; + var mwanConfig = '<br /><br /><span class="description">Output of "cat /etc/config/mwan3" : </span><br /><br />'; + var netConfig = '<br /><br /><span class="description">Output of "cat /etc/config/network" : </span><br /><br />'; + var wifiConfig = '<br /><br /><span class="description">Output of "cat /etc/config/wireless" : </span><br /><br />'; + var ifconfig = '<br /><br /><span class="description">Output of "ifconfig" : </span><br /><br />'; + var ipRoute = '<br /><br /><span class="description">Output of "route -n" : </span><br /><br />'; + var ipRuleShow = '<br /><br /><span class="description">Output of "ip rule show" : </span><br /><br />'; + var routeListTable = '<br /><br /><span class="description">Output of "ip route list table 1-250" : </span><br /><br />'; + var firewallOut = '<br /><br /><span class="description">Firewall default output policy (must be ACCEPT) : </span><br /><br />'; + var iptables = '<br /><br /><span class="description">Output of "iptables -L -t mangle -v -n" : </span><br /><br />'; + tshoot.innerHTML = String.format( + '<pre>%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s</pre>', + versions, mArray.versions[0], mwanConfig, mArray.mwanconfig[0], netConfig, mArray.netconfig[0], + wifiConfig, mArray.wificonfig[0], ifconfig, mArray.ifconfig[0], ipRoute, mArray.routeshow[0], + ipRuleShow, mArray.iprule[0], routeListTable, mArray.routelist[0], firewallOut, mArray.firewallout[0], + iptables, mArray.iptables[0] + ); + } + else + { + tshoot.innerHTML = '<strong>Error collecting troubleshooting information</strong>'; + } + } + ); +//]]></script> + +<div id="troubleshoot"> + <fieldset class="cbi-section"> + <legend><%:Troubleshooting Data%></legend> + <div id="troubleshoot_text"><img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" /> Collecting data...</div> + </fieldset> +</div> + +<style type="text/css"> + .container { /* container for entire page. fixes bootstrap theme's ridiculously small page width */ + max-width: none; + margin-left: 30px; + padding-right: 30px; + width: auto; + } + #troubleshoot { + background-color: #FFFFFF; + border: 1px dotted #555555; + padding: 20px; + } + #troubleshoot_text { + padding: 20px; + text-align: left; + } + .description { + background-color: rgb(78, 186, 241); + } +</style> + +<%+footer%> diff --git a/applications/luci-app-mwan3/luasrc/view/mwan/advanced_wirelessconfig.htm b/applications/luci-app-mwan3/luasrc/view/mwan/advanced_wirelessconfig.htm new file mode 100644 index 0000000000..5077674185 --- /dev/null +++ b/applications/luci-app-mwan3/luasrc/view/mwan/advanced_wirelessconfig.htm @@ -0,0 +1,24 @@ +<ul class="cbi-tabmenu"> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/hotplugscript")%>"><%:Hotplug Script%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/mwanconfig")%>"><%:MWAN Config%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/networkconfig")%>"><%:Network Config%></a></li> + <li class="cbi-tab"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/wirelessconfig")%>"><%:Wireless Config%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/diagnostics")%>"><%:Diagnostics%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/advanced/troubleshooting")%>"><%:Troubleshooting%></a></li> +</ul> + +<style type="text/css"> + .container { /* container for entire page. fixes bootstrap theme's ridiculously small page width */ + max-width: none; + margin: 0px 0px 0px 30px; + padding-right: 30px; + width: auto; + } + .cbi-section-node { + margin-top: 20px; + } + .cbi-section { + border: 1px dotted #555555; + padding: 20px; + } +</style> diff --git a/applications/luci-app-mwan3/luasrc/view/mwan/config_css.htm b/applications/luci-app-mwan3/luasrc/view/mwan/config_css.htm new file mode 100644 index 0000000000..99da4875b0 --- /dev/null +++ b/applications/luci-app-mwan3/luasrc/view/mwan/config_css.htm @@ -0,0 +1,34 @@ +<style type="text/css"> + .container { /* container for entire page. fixes bootstrap theme's ridiculously small page width */ + max-width: none; + margin-left: 30px; + padding-right: 30px; + width: auto; + } + table td { /* cells showing the configuration values */ + padding: 0px; + text-align: center; + vertical-align: middle; + } + table th { /* column for configuration section name */ + padding: 0px; + text-align: center; + vertical-align: middle; + } + table tbody th { /* column for configuration section name */ + padding: 0px; + vertical-align: middle; + } + .cbi-section-node table div { /* rows */ + padding-top: 5px; + } + table.cbi-section-table td.cbi-section-table-cell { /* sort buttons column */ + text-align: center; + } + .cbi-section h3 { + color: rgb(85, 85, 85); + font-family: Trebuchet MS,Verdana,sans-serif; + font-style: italic; + font-weight: normal; + } +</style> diff --git a/applications/luci-app-mwan3/luasrc/view/mwan/openwrt_overview_status.htm b/applications/luci-app-mwan3/luasrc/view/mwan/openwrt_overview_status.htm new file mode 100644 index 0000000000..9329b92735 --- /dev/null +++ b/applications/luci-app-mwan3/luasrc/view/mwan/openwrt_overview_status.htm @@ -0,0 +1,83 @@ +<script type="text/javascript">//<![CDATA[ + XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "network", "mwan", "overview", "interface_status")%>', null, + function(x, mArray) + { + var status = document.getElementById('mwan_status_text'); + if (mArray.wans) + { + var temp = ''; + for ( var i = 0; i < mArray.wans.length; i++ ) + { + var stat = ''; + var cssc = ''; + switch (mArray.wans[i].status) + { + case 'online': + stat = 'Online (tracking active)'; + cssc = 'wanon'; + break; + case 'notMonitored': + stat = 'Online (tracking off)'; + cssc = 'wanon'; + break; + case 'offline': + stat = 'Offline'; + cssc = 'wanoff'; + break; + case 'notEnabled': + stat = 'Disabled'; + cssc = 'wanoff'; + break; + } + temp += String.format( + '<span class="%s"><strong>%s (<a href="%q">%s</a>)</strong><br />%s</span>', + cssc, mArray.wans[i].name, mArray.wans[i].link, mArray.wans[i].ifname, stat + ); + } + status.innerHTML = temp; + } + else + { + status.innerHTML = '<strong>No MWAN interfaces found</strong>'; + } + } + ); +//]]></script> + +<fieldset id="interface_field" class="cbi-section"> + <legend><%:MWAN Interface Live Status%></legend> + <div id="mwan_status_text"><img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" /> Collecting data...</div> +</fieldset> + +<style type="text/css"> + .container { /* container for entire page. fixes bootstrap theme's ridiculously small page width */ + max-width: 1044px; + } + #interface_field { + padding: 12px 20px 20px 20px; + } + #mwan_status_text { + display: table; + font-size: 14px; + margin: auto; + max-width: 1044px; + min-width: 246px; + width: 100%; + } + .wanon { + background-color: rgb(144, 240, 144); + } + .wanoff { + background-color: rgb(240, 144, 144); + } + .wanon, .wanoff { + border-radius: 60px; + box-shadow: 0px 2px 5px -3px; + float: left; + margin: 8px 3px 0px 3px; + min-height: 30px; + min-width: 235px; + padding: 5px 10px 8px 10px; + text-align: center; + } +</style> diff --git a/applications/luci-app-mwan3/luasrc/view/mwan/overview_detailed.htm b/applications/luci-app-mwan3/luasrc/view/mwan/overview_detailed.htm new file mode 100644 index 0000000000..b80b9f3acf --- /dev/null +++ b/applications/luci-app-mwan3/luasrc/view/mwan/overview_detailed.htm @@ -0,0 +1,51 @@ +<%+header%> + +<ul class="cbi-tabmenu"> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/overview")%>"><%:Interface Status%></a></li> + <li class="cbi-tab"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/overview/overview_detailed")%>"><%:Detailed Status%></a></li> +</ul> + +<script type="text/javascript" src="<%=resource%>/cbi.js"></script> +<script type="text/javascript">//<![CDATA[ + XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "network", "mwan", "overview", "detailed_status")%>', null, + function(x, mArray) + { + var status = document.getElementById('mwan_detail_text'); + if (mArray.mwandetail) + { + status.innerHTML = String.format('<pre>%s</pre>', mArray.mwandetail[0]); + } + else + { + status.innerHTML = '<strong>No detailed status information available</strong>'; + } + } + ); +//]]></script> + +<div id="mwan_detail_status"> + <fieldset class="cbi-section"> + <legend><%:MWAN Detailed Status%></legend> + <div id="mwan_detail_text"><img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" /> Collecting data...</div> + </fieldset> +</div> + +<style type="text/css"> + .container { /* container for entire page. fixes bootstrap theme's ridiculously small page width */ + max-width: none; + margin-left: 30px; + padding-right: 30px; + width: auto; + } + #mwan_detail_status { + border: 1px dotted #555555; + background-color: #FFFFFF; + padding: 20px; + } + #mwan_detail_text { + padding: 20px; + text-align: left; + } +</style> + +<%+footer%> diff --git a/applications/luci-app-mwan3/luasrc/view/mwan/overview_interface.htm b/applications/luci-app-mwan3/luasrc/view/mwan/overview_interface.htm new file mode 100644 index 0000000000..472c7ce7fc --- /dev/null +++ b/applications/luci-app-mwan3/luasrc/view/mwan/overview_interface.htm @@ -0,0 +1,122 @@ +<%+header%> + +<ul class="cbi-tabmenu"> + <li class="cbi-tab"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/overview")%>"><%:Interface Status%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan/overview/overview_detailed")%>"><%:Detailed Status%></a></li> +</ul> + +<script type="text/javascript" src="<%=resource%>/cbi.js"></script> +<script type="text/javascript">//<![CDATA[ + XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "network", "mwan", "overview", "interface_status")%>', null, + function(x, mArray) + { + var statusDiv = document.getElementById('mwan_status_text'); + if (mArray.wans) + { + var interfaceStatus = ''; + for ( var i = 0; i < mArray.wans.length; i++ ) + { + var status = ''; + var css = ''; + switch (mArray.wans[i].status) + { + case 'online': + status = 'Online (tracking active)'; + css = 'wanon'; + break; + case 'notMonitored': + status = 'Online (tracking off)'; + css = 'wanon'; + break; + case 'offline': + status = 'Offline'; + css = 'wanoff'; + break; + case 'notEnabled': + status = 'Disabled'; + css = 'wanoff'; + break; + } + interfaceStatus += String.format( + '<span class="%s"><strong>%s (<a href="%q">%s</a>)</strong><br />%s</span>', + css, mArray.wans[i].name, mArray.wans[i].link, mArray.wans[i].ifname, status + ); + } + statusDiv.innerHTML = interfaceStatus; + } + else + { + statusDiv.innerHTML = '<strong>No MWAN interfaces found</strong>'; + } + + var logs = document.getElementById('mwan_statuslog_text'); + if (mArray.mwanlog) + { + var mwanLog = 'Last 50 MWAN systemlog entries. Newest entries sorted at the top :'; + logs.innerHTML = String.format('<pre>%s<br /><br />%s</pre>', mwanLog, mArray.mwanlog[0]); + } + else + { + logs.innerHTML = '<strong>No MWAN systemlog history found</strong>'; + } + } + ); +//]]></script> + +<div id="mwan_interface_status"> + <fieldset id="interface_field" class="cbi-section"> + <legend><%:MWAN Interface Live Status%></legend> + <div id="mwan_status_text"><img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" /> Collecting data...</div> + </fieldset> + <fieldset class="cbi-section"> + <legend><%:MWAN Interface Systemlog%></legend> + <div id="mwan_statuslog_text"><img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" /> Collecting data...</div> + </fieldset> +</div> + +<style type="text/css"> + .container { /* container for entire page. fixes bootstrap theme's ridiculously small page width */ + max-width: none; + margin-left: 30px; + padding-right: 30px; + width: auto; + } + #mwan_interface_status { + background-color: #FFFFFF; + border: 1px dotted #555555; + padding: 20px; + } + #interface_field { + padding: 12px 20px 20px 20px; + } + #mwan_status_text { + display: table; + font-size: 14px; + margin: auto; + max-width: 1044px; + min-width: 246px; + width: 100%; + } + .wanon { + background-color: rgb(144, 240, 144); + } + .wanoff { + background-color: rgb(240, 144, 144); + } + .wanon, .wanoff { + border-radius: 60px; + box-shadow: 0px 2px 5px -3px; + float: left; + margin: 8px 3px 0px 3px; + min-height: 30px; + min-width: 235px; + padding: 5px 10px 8px 10px; + text-align: center; + } + #mwan_statuslog_text { + padding: 20px; + text-align: left; + } +</style> + +<%+footer%> diff --git a/applications/luci-app-mwan3/root/etc/hotplug.d/iface/16-mwancustombak b/applications/luci-app-mwan3/root/etc/hotplug.d/iface/16-mwancustombak new file mode 100755 index 0000000000..6e2875e3de --- /dev/null +++ b/applications/luci-app-mwan3/root/etc/hotplug.d/iface/16-mwancustombak @@ -0,0 +1,38 @@ +#!/bin/sh + +# to enable this script uncomment the case loop at the bottom +# to report mwan status on interface hotplug ifup/ifdown events modify the lines in the send_alert function + +send_alert() +{ + # variable "$1" stores the MWAN status information + # insert your code here to send the contents of "$1" + echo "$1" +} + +gather_event_info() +{ + # create event information message + local EVENT_INFO="Interface [ "$INTERFACE" ($DEVICE) ] on router [ "$(uci -p /var/state get system.@system[0].hostname)" ] has triggered a hotplug [ "$ACTION" ] event on "$(date +"%a %b %d %Y %T %Z")"" + + # get current interface, policy and rule status + local CURRENT_STATUS="$(/usr/sbin/mwan3 status)" + + # get last 50 MWAN systemlog messages + local MWAN_LOG="$(echo -e "Last 50 MWAN systemlog entries. Newest entries sorted at the top:\n$(logread | grep mwan3 | tail -n 50 | sed 'x;1!H;$!d;x')")" + + # pass event info to send_alert function + send_alert "$(echo -e "$EVENT_INFO\n\n$CURRENT_STATUS\n\n$MWAN_LOG")" +} + +#case "$ACTION" in +# ifup) +# gather_event_info +# ;; +# +# ifdown) +# gather_event_info +# ;; +#esac + +exit 0 diff --git a/applications/luci-app-mwan3/root/etc/uci-defaults/60_luci-mwan3 b/applications/luci-app-mwan3/root/etc/uci-defaults/60_luci-mwan3 new file mode 100755 index 0000000000..ff9a229edd --- /dev/null +++ b/applications/luci-app-mwan3/root/etc/uci-defaults/60_luci-mwan3 @@ -0,0 +1,14 @@ +#!/bin/sh + +# replace existing mwan ucitrack entry +uci -q batch <<-EOF >/dev/null + del ucitrack.@mwan3[-1] + add ucitrack mwan3 + set ucitrack.@mwan3[-1].exec="/usr/sbin/mwan3 restart" + commit ucitrack +EOF + +# remove LuCI cache +rm -rf /tmp/luci-indexcache /tmp/luci-modulecache + +exit 0 diff --git a/applications/luci-app-openvpn/luasrc/model/cbi/openvpn-advanced.lua b/applications/luci-app-openvpn/luasrc/model/cbi/openvpn-advanced.lua index 1bbee83c35..d0771e5830 100644 --- a/applications/luci-app-openvpn/luasrc/model/cbi/openvpn-advanced.lua +++ b/applications/luci-app-openvpn/luasrc/model/cbi/openvpn-advanced.lua @@ -7,192 +7,722 @@ require("luci.model.uci") local knownParams = { -- - -- Widget Name Default(s) Description Option(s) - -- + --Widget + -- Name + -- Default(s) + -- Description + -- Option(s) { "Service", { - -- initialisation and daemon options - { ListValue, "verb", { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }, translate("Set output verbosity") }, - { Flag, "mlock", 0, translate("Disable Paging") }, - { Flag, "disable_occ", 0, translate("Disable options consistency check") }, - -- { Value, "user", "root", translate("Set UID to user") }, - -- { Value, "group", "root", translate("Set GID to group") }, - { Value, "cd", "/etc/openvpn", translate("Change to directory before initialization") }, - { Value, "chroot", "/var/run", translate("Chroot to directory after initialization") }, - -- { Value, "daemon", "Instance-Name", translate("Daemonize after initialization") }, - -- { Value, "syslog", "Instance-Name", translate("Output to syslog and do not daemonize") }, - { Flag, "passtos", 0, translate("TOS passthrough (applies to IPv4 only)") }, - -- { Value, "inetd", "nowait Instance-Name", translate("Run as an inetd or xinetd server") }, - { Value, "log", "/var/log/openvpn.log", translate("Write log to file") }, - { Value, "log_append", "/var/log/openvpn.log", translate("Append log to file") }, - { Flag, "suppress_timestamps", 0, translate("Don't log timestamps") }, - -- { Value, "writepid", "/var/run/openvpn.pid", translate("Write process ID to file") }, - { Value, "nice", 0, translate("Change process priority") }, - { Flag, "fast_io", 0, translate("Optimize TUN/TAP/UDP writes") }, - { Value, "echo", "some params echoed to log", translate("Echo parameters to log") }, - { ListValue, "remap_usr1", { "SIGHUP", "SIGTERM" }, translate("Remap SIGUSR1 signals") }, - { Value, "status", "/var/run/openvpn.status 5", translate("Write status to file every n seconds") }, - { Value, "status_version", { 1, 2 }, translate("Status file format version") }, -- status - { Value, "mute", 5, translate("Limit repeated log messages") }, - - { Value, "up", "/usr/bin/ovpn-up", translate("Shell cmd to execute after tun device open") }, - { Value, "up_delay", 5, translate("Delay tun/tap open and up script execution") }, - { Value, "down", "/usr/bin/ovpn-down", translate("Shell cmd to run after tun device close") }, - { Flag, "down_pre", 0, translate("Call down cmd/script before TUN/TAP close") }, - { Flag, "up_restart", 0, translate("Run up/down scripts for all restarts") }, - { Value, "route_up", "/usr/bin/ovpn-routeup", translate("Execute shell cmd after routes are added") }, - { Value, "ipchange", "/usr/bin/ovpn-ipchange", translate("Execute shell command on remote ip change"), { mode="p2p" } }, - { DynamicList, "setenv", { "VAR1 value1", "VAR2 value2" }, translate("Pass environment variables to script") }, - { Value, "tls_verify", "/usr/bin/ovpn-tlsverify", translate("Shell command to verify X509 name") }, - { Value, "client_connect", "/usr/bin/ovpn-clientconnect", translate("Run script cmd on client connection") }, - { Flag, "client_disconnect", 0, translate("Run script cmd on client disconnection") }, - { Value, "learn_address", "/usr/bin/ovpn-learnaddress", translate("Executed in server mode whenever an IPv4 address/route or MAC address is added to OpenVPN's internal routing table") }, - { Value, "auth_user_pass_verify", "/usr/bin/ovpn-userpass via-env", translate("Executed in server mode on new client connections, when the client is still untrusted") }, - { ListValue, "script_security", { 0, 1, 2, 3 }, translate("Policy level over usage of external programs and scripts") }, + -- initialisation and daemon options + { ListValue, + "verb", + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }, + translate("Set output verbosity") }, + { Flag, + "mlock", + 0, + translate("Disable Paging") }, + { Flag, + "disable_occ", + 0, + translate("Disable options consistency check") }, + -- { Value, + -- "user", + -- "root", + -- translate("Set UID to user") }, + -- { Value, + -- "group", + -- "root", + -- translate("Set GID to group") }, + { Value, + "cd", + "/etc/openvpn", + translate("Change to directory before initialization") }, + { Value, + "chroot", + "/var/run", + translate("Chroot to directory after initialization") }, + -- { Value, + -- "daemon", + -- "Instance-Name", + -- translate("Daemonize after initialization") }, + -- { Value, + -- "syslog", + -- "Instance-Name", + -- translate("Output to syslog and do not daemonize") }, + { Flag, + "passtos", + 0, + translate("TOS passthrough (applies to IPv4 only)") }, + -- { Value, + -- "inetd", + -- "nowait Instance-Name", + -- translate("Run as an inetd or xinetd server") }, + { Value, + "log", + "/var/log/openvpn.log", + translate("Write log to file") }, + { Value, + "log_append", + "/var/log/openvpn.log", + translate("Append log to file") }, + { Flag, + "suppress_timestamps", + 0, + translate("Don't log timestamps") }, + -- { Value, + -- "writepid", + -- "/var/run/openvpn.pid", + -- translate("Write process ID to file") }, + { Value, + "nice", + 0, + translate("Change process priority") }, + { Flag, + "fast_io", + 0, + translate("Optimize TUN/TAP/UDP writes") }, + { Value, + "echo", + "some params echoed to log", + translate("Echo parameters to log") }, + { ListValue, + "remap_usr1", + { "SIGHUP", "SIGTERM" }, + translate("Remap SIGUSR1 signals") }, + { Value, + "status", + "/var/run/openvpn.status 5", + translate("Write status to file every n seconds") }, + { Value, + "status_version", + { 1, 2 }, + translate("Status file format version") }, -- status + { Value, + "mute", + 5, + translate("Limit repeated log messages") }, + { Value, + "up", + "/usr/bin/ovpn-up", + translate("Shell cmd to execute after tun device open") }, + { Value, + "up_delay", + 5, + translate("Delay tun/tap open and up script execution") }, + { Value, + "down", + "/usr/bin/ovpn-down", + translate("Shell cmd to run after tun device close") }, + { Flag, + "down_pre", + 0, + translate("Call down cmd/script before TUN/TAP close") }, + { Flag, + "up_restart", + 0, + translate("Run up/down scripts for all restarts") }, + { Value, + "route_up", + "/usr/bin/ovpn-routeup", + translate("Execute shell cmd after routes are added") }, + { Value, + "ipchange", + "/usr/bin/ovpn-ipchange", + translate("Execute shell command on remote ip change"), + { mode="p2p" } }, + { DynamicList, + "setenv", + { "VAR1 value1", "VAR2 value2" }, + translate("Pass environment variables to script") }, + { Value, + "tls_verify", + "/usr/bin/ovpn-tlsverify", + translate("Shell command to verify X509 name") }, + { Value, + "client_connect", + "/usr/bin/ovpn-clientconnect", + translate("Run script cmd on client connection") }, + { Flag, + "client_disconnect", + 0, + translate("Run script cmd on client disconnection") }, + { Value, + "learn_address", + "/usr/bin/ovpn-learnaddress", + translate("Executed in server mode whenever an IPv4 address/route or MAC address is added to OpenVPN's internal routing table") }, + { Value, + "auth_user_pass_verify", + "/usr/bin/ovpn-userpass via-env", + translate("Executed in server mode on new client connections, when the client is still untrusted") }, + { ListValue, + "script_security", + { 0, 1, 2, 3 }, + translate("Policy level over usage of external programs and scripts") }, } }, { "Networking", { - -- socket config - { ListValue, "mode", { "p2p", "server" }, translate("Major mode") }, - { Value, "local", "0.0.0.0", translate("Local host name or ip address") }, - { Value, "port", 1194, translate("TCP/UDP port # for both local and remote") }, - { Value, "lport", 1194, translate("TCP/UDP port # for local (default=1194)") }, - { Value, "rport", 1194, translate("TCP/UDP port # for remote (default=1194)") }, - { Flag, "float", 0, translate("Allow remote to change its IP or port") }, - { Flag, "nobind", 0, translate("Do not bind to local address and port") }, - - { Value, "dev", "tun0", translate("tun/tap device") }, - { ListValue, "dev_type", { "tun", "tap" }, translate("Type of used device") }, - { Value, "dev_node", "/dev/net/tun", translate("Use tun/tap device node") }, - { Flag, "tun_ipv6", 0, translate("Make tun device IPv6 capable") }, - - { Value, "ifconfig", "10.200.200.3 10.200.200.1", translate("Set tun/tap adapter parameters") }, - { Flag, "ifconfig_noexec", 0, translate("Don't actually execute ifconfig") }, - { Flag, "ifconfig_nowarn", 0, translate("Don't warn on ifconfig inconsistencies") }, - - { DynamicList, "route", "10.123.0.0 255.255.0.0", translate("Add route after establishing connection") }, - { Value, "route_gateway", "10.234.1.1", translate("Specify a default gateway for routes") }, - { Value, "route_delay", 0, translate("Delay n seconds after connection") }, - { Flag, "route_noexec", 0, translate("Don't add routes automatically") }, - { Flag, "route_nopull", 0, translate("Don't pull routes automatically") }, - - { ListValue, "mtu_disc", { "yes", "maybe", "no" }, translate("Enable Path MTU discovery") }, - { Flag, "mtu_test", 0, translate("Empirically measure MTU") }, - { ListValue, "comp_lzo", { "yes", "no", "adaptive" }, translate("Use fast LZO compression") }, - { Flag, "comp_noadapt", 0, translate("Don't use adaptive lzo compression"), { comp_lzo=1 } }, - { Value, "link_mtu", 1500, translate("Set TCP/UDP MTU") }, - { Value, "tun_mtu", 1500, translate("Set tun/tap device MTU") }, - { Value, "tun_mtu_extra", 1500, translate("Set tun/tap device overhead") }, - { Value, "fragment", 1500, translate("Enable internal datagram fragmentation"), { proto="udp" } }, - { Value, "mssfix", 1500, translate("Set upper bound on TCP MSS"), { proto="udp" } }, - { Value, "sndbuf", 65536, translate("Set the TCP/UDP send buffer size") }, - { Value, "rcvbuf", 65536, translate("Set the TCP/UDP receive buffer size") }, - { Value, "txqueuelen", 100, translate("Set tun/tap TX queue length") }, - { Value, "shaper", 10240, translate("Shaping for peer bandwidth") }, - - { Value, "inactive", 240, translate("tun/tap inactivity timeout") }, - { Value, "keepalive", "10 60", translate("Helper directive to simplify the expression of --ping and --ping-restart in server mode configurations") }, - { Value, "ping", 30, translate("Ping remote every n seconds over TCP/UDP port") }, - { Value, "ping_exit", 120, translate("Remote ping timeout") }, - { Value, "ping_restart", 60, translate("Restart after remote ping timeout") }, - { Flag, "ping_timer_rem", 0, translate("Only process ping timeouts if routes exist") }, - - { Flag, "persist_tun", 0, translate("Keep tun/tap device open on restart") }, - { Flag, "persist_key", 0, translate("Don't re-read key on restart") }, - { Flag, "persist_local_ip", 0, translate("Keep local IP address on restart") }, - { Flag, "persist_remote_ip", 0, translate("Keep remote IP address on restart") }, - - -- management channel - { Value, "management", "127.0.0.1 31194 /etc/openvpn/mngmt-pwds", translate("Enable management interface on <em>IP</em> <em>port</em>") }, - { Flag, "management_query_passwords", 0, translate("Query management channel for private key") }, -- management - { Flag, "management_hold", 0, translate("Start OpenVPN in a hibernating state") }, -- management - { Value, "management_log_cache", 100, translate("Number of lines for log file history") }, -- management - { ListValue, "topology", { "net30", "p2p", "subnet" }, translate("'net30', 'p2p', or 'subnet'"), {dev_type="tun" } }, + -- socket config + { ListValue, + "mode", + { "p2p", "server" }, + translate("Major mode") }, + { Value, + "local", + "0.0.0.0", + translate("Local host name or ip address") }, + { Value, + "port", + 1194, + translate("TCP/UDP port # for both local and remote") }, + { Value, + "lport", + 1194, + translate("TCP/UDP port # for local (default=1194)") }, + { Value, + "rport", + 1194, + translate("TCP/UDP port # for remote (default=1194)") }, + { Flag, + "float", + 0, + translate("Allow remote to change its IP or port") }, + { Flag, + "nobind", + 0, + translate("Do not bind to local address and port") }, + { Value, + "dev", + "tun0", + translate("tun/tap device") }, + { ListValue, + "dev_type", + { "tun", "tap" }, + translate("Type of used device") }, + { Value, + "dev_node", + "/dev/net/tun", + translate("Use tun/tap device node") }, + { Flag, + "tun_ipv6", + 0, + translate("Make tun device IPv6 capable") }, + { Value, + "ifconfig", + "10.200.200.3 10.200.200.1", + translate("Set tun/tap adapter parameters") }, + { Flag, + "ifconfig_noexec", + 0, + translate("Don't actually execute ifconfig") }, + { Flag, + "ifconfig_nowarn", + 0, + translate("Don't warn on ifconfig inconsistencies") }, + { DynamicList, + "route", + "10.123.0.0 255.255.0.0", + translate("Add route after establishing connection") }, + { Value, + "route_gateway", + "10.234.1.1", + translate("Specify a default gateway for routes") }, + { Value, + "route_delay", + 0, + translate("Delay n seconds after connection") }, + { Flag, + "route_noexec", + 0, + translate("Don't add routes automatically") }, + { Flag, + "route_nopull", + 0, + translate("Don't pull routes automatically") }, + { ListValue, + "mtu_disc", + { "yes", "maybe", "no" }, + translate("Enable Path MTU discovery") }, + { Flag, + "mtu_test", + 0, + translate("Empirically measure MTU") }, + { ListValue, + "comp_lzo", + { "yes", "no", "adaptive" }, + translate("Use fast LZO compression") }, + { Flag, + "comp_noadapt", + 0, + translate("Don't use adaptive lzo compression"), + { comp_lzo=1 } }, + { Value, + "link_mtu", + 1500, + translate("Set TCP/UDP MTU") }, + { Value, + "tun_mtu", + 1500, + translate("Set tun/tap device MTU") }, + { Value, + "tun_mtu_extra", + 1500, + translate("Set tun/tap device overhead") }, + { Value, + "fragment", + 1500, + translate("Enable internal datagram fragmentation"), + { proto="udp" } }, + { Value, + "mssfix", + 1500, + translate("Set upper bound on TCP MSS"), + { proto="udp" } }, + { Value, + "sndbuf", + 65536, + translate("Set the TCP/UDP send buffer size") }, + { Value, + "rcvbuf", + 65536, + translate("Set the TCP/UDP receive buffer size") }, + { Value, + "txqueuelen", + 100, + translate("Set tun/tap TX queue length") }, + { Value, + "shaper", + 10240, + translate("Shaping for peer bandwidth") }, + { Value, + "inactive", + 240, + translate("tun/tap inactivity timeout") }, + { Value, + "keepalive", + "10 60", + translate("Helper directive to simplify the expression of --ping and --ping-restart in server mode configurations") }, + { Value, + "ping", + 30, + translate("Ping remote every n seconds over TCP/UDP port") }, + { Value, + "ping_exit", + 120, + translate("Remote ping timeout") }, + { Value, + "ping_restart", + 60, + translate("Restart after remote ping timeout") }, + { Flag, + "ping_timer_rem", + 0, + translate("Only process ping timeouts if routes exist") }, + { Flag, + "persist_tun", + 0, + translate("Keep tun/tap device open on restart") }, + { Flag, + "persist_key", + 0, + translate("Don't re-read key on restart") }, + { Flag, + "persist_local_ip", + 0, + translate("Keep local IP address on restart") }, + { Flag, + "persist_remote_ip", + 0, + translate("Keep remote IP address on restart") }, + -- management channel + { Value, + "management", + "127.0.0.1 31194 /etc/openvpn/mngmt-pwds", + translate("Enable management interface on <em>IP</em> <em>port</em>") }, + -- management + { Flag, + "management_query_passwords", + 0, + translate("Query management channel for private key") }, + -- management + { Flag, + "management_hold", + 0, + translate("Start OpenVPN in a hibernating state") }, + -- management + { Value, + "management_log_cache", + 100, + translate("Number of lines for log file history") }, + { ListValue, + "topology", + { "net30", "p2p", "subnet" }, + translate("'net30', 'p2p', or 'subnet'"), + {dev_type="tun" } }, } }, { "VPN", { - { Value, "server", "10.200.200.0 255.255.255.0", translate("Configure server mode"), { server_mode="1" } }, - { Value, "server_bridge", "10.200.200.1 255.255.255.0 10.200.200.200 10.200.200.250", translate("Configure server bridge"), { server_mode="1" } }, - { DynamicList, "push", { "redirect-gateway", "comp-lzo" }, translate("Push options to peer"), { server_mode="1" } }, - { Flag, "push_reset", 0, translate("Don't inherit global push options"), { server_mode="1" } }, - { Flag, "disable", 0, translate("Client is disabled"), { server_mode="1" } }, - { Value, "ifconfig_pool", "10.200.200.100 10.200.200.150 255.255.255.0", translate("Set aside a pool of subnets"), { server_mode="1" } }, - { Value, "ifconfig_pool_persist", "/etc/openvpn/ipp.txt 600", translate("Persist/unpersist ifconfig-pool"), { server_mode="1" } }, --- { Flag, "ifconfig_pool_linear", 0, translate("Use individual addresses rather than /30 subnets"), { server_mode="1" } }, -- deprecated and replaced by --topology p2p - { Value, "ifconfig_push", "10.200.200.1 255.255.255.255", translate("Push an ifconfig option to remote"), { server_mode="1" } }, - { Value, "iroute", "10.200.200.0 255.255.255.0", translate("Route subnet to client"), { server_mode="1" } }, - { Flag, "client_to_client", 0, translate("Allow client-to-client traffic"), { server_mode="1" } }, - { Flag, "duplicate_cn", 0, translate("Allow multiple clients with same certificate"), { server_mode="1" } }, - { Value, "client_config_dir", "/etc/openvpn/ccd", translate("Directory for custom client config files"), { server_mode="1" } }, - { Flag, "ccd_exclusive", 0, translate("Refuse connection if no custom client config"), { server_mode="1" } }, - { Value, "tmp_dir", "/var/run/openvpn", translate("Temporary directory for client-connect return file"), { server_mode="1" } }, - { Value, "hash_size", "256 256", translate("Set size of real and virtual address hash tables"), { server_mode="1" } }, - { Value, "bcast_buffers", 256, translate("Number of allocated broadcast buffers"), { server_mode="1" } }, - { Value, "tcp_queue_limit", 64, translate("Maximum number of queued TCP output packets"), { server_mode="1" } }, - { Value, "max_clients", 10, translate("Allowed maximum of connected clients"), { server_mode="1" } }, - { Value, "max_routes_per_client", 256, translate("Allowed maximum of internal"), { server_mode="1" } }, - { Value, "connect_freq", "3 10", translate("Allowed maximum of new connections"), { server_mode="1" } }, - { Flag, "client_cert_not_required", 0, translate("Don't require client certificate"), { server_mode="1" } }, - { Flag, "username_as_common_name", 0, translate("Use username as common name"), { server_mode="1" } }, - { Flag, "client", 0, translate("Configure client mode"), { server_mode="0" }, { server_mode="" } }, - { Flag, "pull", 0, translate("Accept options pushed from server"), { client="1" } }, - { Value, "auth_user_pass", "/etc/openvpn/userpass.txt", translate("Authenticate using username/password"), { client="1" } }, - { ListValue, "auth_retry", { "none", "nointeract", "interact" }, translate("Handling of authentication failures"), { client="1" } }, - { Value, "explicit_exit_notify", 1, translate("Send notification to peer on disconnect"), { client="1" } }, - { DynamicList, "remote", "1.2.3.4", translate("Remote host name or ip address"), { client="1" } }, - { Flag, "remote_random", 1, translate("Randomly choose remote server"), { client="1" } }, - { ListValue, "proto", { "udp", "tcp-client", "tcp-server" }, translate("Use protocol"), { client="1" } }, - { Value, "connect_retry", 5, translate("Connection retry interval"), { proto="tcp-client" }, { client="1" } }, - { Value, "http_proxy", "192.168.1.100 8080", translate("Connect to remote host through an HTTP proxy"), { client="1" } }, - { Flag, "http_proxy_retry", 0, translate("Retry indefinitely on HTTP proxy errors"), { client="1" } }, - { Value, "http_proxy_timeout", 5, translate("Proxy timeout in seconds"), { client="1" } }, - { DynamicList, "http_proxy_option", { "VERSION 1.0", "AGENT OpenVPN/2.0.9" }, translate("Set extended HTTP proxy options"), { client="1" } }, - { Value, "socks_proxy", "192.168.1.200 1080", translate("Connect through Socks5 proxy"), { client="1" } }, - { Value, "socks_proxy_retry", 5, translate("Retry indefinitely on Socks proxy errors"), { client="1" } }, -- client && socks_proxy - { Value, "resolv_retry", "infinite", translate("If hostname resolve fails, retry"), { client="1" } }, - { ListValue, "redirect_gateway", { "", "local", "def1", "local def1" }, translate("Automatically redirect default route"), { client="1" } }, + { Value, + "server", + "10.200.200.0 255.255.255.0", + translate("Configure server mode"), + { server_mode="1" } }, + { Value, + "server_bridge", + "10.200.200.1 255.255.255.0 10.200.200.200 10.200.200.250", + translate("Configure server bridge"), + { server_mode="1" } }, + { DynamicList, + "push", + { "redirect-gateway", "comp-lzo" }, + translate("Push options to peer"), + { server_mode="1" } }, + { Flag, + "push_reset", + 0, + translate("Don't inherit global push options"), + { server_mode="1" } }, + { Flag, + "disable", + 0, + translate("Client is disabled"), + { server_mode="1" } }, + { Value, + "ifconfig_pool", + "10.200.200.100 10.200.200.150 255.255.255.0", + translate("Set aside a pool of subnets"), + { server_mode="1" } }, + { Value, + "ifconfig_pool_persist", + "/etc/openvpn/ipp.txt 600", + translate("Persist/unpersist ifconfig-pool"), + { server_mode="1" } }, + -- deprecated and replaced by --topology p2p + -- { Flag, + -- "ifconfig_pool_linear", + -- 0, + -- translate("Use individual addresses rather than /30 subnets"), + -- { server_mode="1" } }, + { Value, + "ifconfig_push", + "10.200.200.1 255.255.255.255", + translate("Push an ifconfig option to remote"), + { server_mode="1" } }, + { Value, + "iroute", + "10.200.200.0 255.255.255.0", + translate("Route subnet to client"), + { server_mode="1" } }, + { Flag, + "client_to_client", + 0, + translate("Allow client-to-client traffic"), + { server_mode="1" } }, + { Flag, + "duplicate_cn", + 0, + translate("Allow multiple clients with same certificate"), + { server_mode="1" } }, + { Value, + "client_config_dir", + "/etc/openvpn/ccd", + translate("Directory for custom client config files"), + { server_mode="1" } }, + { Flag, + "ccd_exclusive", + 0, + translate("Refuse connection if no custom client config"), + { server_mode="1" } }, + { Value, + "tmp_dir", + "/var/run/openvpn", + translate("Temporary directory for client-connect return file"), + { server_mode="1" } }, + { Value, + "hash_size", + "256 256", + translate("Set size of real and virtual address hash tables"), + { server_mode="1" } }, + { Value, + "bcast_buffers", + 256, + translate("Number of allocated broadcast buffers"), + { server_mode="1" } }, + { Value, + "tcp_queue_limit", + 64, + translate("Maximum number of queued TCP output packets"), + { server_mode="1" } }, + { Value, + "max_clients", + 10, + translate("Allowed maximum of connected clients"), + { server_mode="1" } }, + { Value, + "max_routes_per_client", + 256, + translate("Allowed maximum of internal"), + { server_mode="1" } }, + { Value, + "connect_freq", + "3 10", + translate("Allowed maximum of new connections"), + { server_mode="1" } }, + { Flag, + "client_cert_not_required", + 0, + translate("Don't require client certificate"), + { server_mode="1" } }, + { Flag, + "username_as_common_name", + 0, + translate("Use username as common name"), + { server_mode="1" } }, + { Flag, + "client", + 0, + translate("Configure client mode"), + { server_mode="0" }, { server_mode="" } }, + { Flag, + "pull", + 0, + translate("Accept options pushed from server"), + { client="1" } }, + { Value, + "auth_user_pass", + "/etc/openvpn/userpass.txt", + translate("Authenticate using username/password"), + { client="1" } }, + { ListValue, + "auth_retry", + { "none", "nointeract", "interact" }, + translate("Handling of authentication failures"), + { client="1" } }, + { Value, + "explicit_exit_notify", + 1, + translate("Send notification to peer on disconnect"), + { client="1" } }, + { DynamicList, + "remote", + "1.2.3.4", + translate("Remote host name or ip address"), + { client="1" } }, + { Flag, + "remote_random", + 1, + translate("Randomly choose remote server"), + { client="1" } }, + { ListValue, + "proto", + { "udp", "tcp-client", "tcp-server" }, + translate("Use protocol"), + { client="1" } }, + { Value, + "connect_retry", + 5, + translate("Connection retry interval"), + { proto="tcp-client" }, { client="1" } }, + { Value, + "http_proxy", + "192.168.1.100 8080", + translate("Connect to remote host through an HTTP proxy"), + { client="1" } }, + { Flag, + "http_proxy_retry", + 0, + translate("Retry indefinitely on HTTP proxy errors"), + { client="1" } }, + { Value, + "http_proxy_timeout", + 5, + translate("Proxy timeout in seconds"), + { client="1" } }, + { DynamicList, + "http_proxy_option", + { "VERSION 1.0", "AGENT OpenVPN/2.0.9" }, + translate("Set extended HTTP proxy options"), + { client="1" } }, + { Value, + "socks_proxy", + "192.168.1.200 1080", + translate("Connect through Socks5 proxy"), + { client="1" } }, + -- client && socks_proxy + { Value, + "socks_proxy_retry", + 5, + translate("Retry indefinitely on Socks proxy errors"), + { client="1" } }, + { Value, + "resolv_retry", + "infinite", + translate("If hostname resolve fails, retry"), + { client="1" } }, + { ListValue, + "redirect_gateway", + { "", "local", "def1", "local def1" }, + translate("Automatically redirect default route"), + { client="1" } }, } }, { "Cryptography", { - { FileUpload, "secret", "/etc/openvpn/secret.key", translate("Enable Static Key encryption mode (non-TLS)") }, - { Value, "auth", "SHA1", translate("HMAC authentication for packets") }, -- parse - { Value, "cipher", "BF-CBC", translate("Encryption cipher for packets") }, -- parse - { Value, "keysize", 1024, translate("Size of cipher key") }, -- parse - { Value, "engine", "dynamic", translate("Enable OpenSSL hardware crypto engines") }, -- parse - { Flag, "no_replay", 0, translate("Disable replay protection") }, - { Value, "replay_window", "64 15", translate("Replay protection sliding window size") }, - { Flag, "mute_replay_warnings", 0, translate("Silence the output of replay warnings") }, - { Value, "replay_persist", "/var/run/openvpn-replay-state", translate("Persist replay-protection state") }, - { Flag, "no_iv", 0, translate("Disable cipher initialisation vector") }, - { Flag, "tls_server", 0, translate("Enable TLS and assume server role"), { tls_client="" }, { tls_client="0" } }, - { Flag, "tls_client", 0, translate("Enable TLS and assume client role"), { tls_server="" }, { tls_server="0" } }, - { FileUpload, "ca", "/etc/easy-rsa/keys/ca.crt", translate("Certificate authority") }, - { FileUpload, "dh", "/etc/easy-rsa/keys/dh1024.pem", translate("Diffie Hellman parameters") }, - { FileUpload, "cert", "/etc/easy-rsa/keys/some-client.crt", translate("Local certificate") }, - { FileUpload, "key", "/etc/easy-rsa/keys/some-client.key", translate("Local private key") }, - { FileUpload, "pkcs12", "/etc/easy-rsa/keys/some-client.pk12", translate("PKCS#12 file containing keys") }, - { ListValue, "key_method", { 1, 2 }, translate("Enable TLS and assume client role") }, - { Value, "tls_cipher", "DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:AES256-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DES-CBC3-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:AES128-SHA:RC4-SHA:RC4-MD5:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DES-CBC-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-RC4-MD5", - translate("TLS cipher") }, - { Value, "tls_timeout", 2, translate("Retransmit timeout on TLS control channel") }, - { Value, "reneg_bytes", 1024, translate("Renegotiate data chan. key after bytes") }, - { Value, "reneg_pkts", 100, translate("Renegotiate data chan. key after packets") }, - { Value, "reneg_sec", 3600, translate("Renegotiate data chan. key after seconds") }, - { Value, "hand_window", 60, translate("Timeframe for key exchange") }, - { Value, "tran_window", 3600, translate("Key transition window") }, - { Flag, "single_session", 0, translate("Allow only one session") }, - { Flag, "tls_exit", 0, translate("Exit on TLS negotiation failure") }, - { Value, "tls_auth", "/etc/openvpn/tlsauth.key", translate("Additional authentication over TLS") }, - --{ Value, "askpass", "[file]", translate("Get PEM password from controlling tty before we daemonize") }, - { Flag, "auth_nocache", 0, translate("Don't cache --askpass or --auth-user-pass passwords") }, - { Value, "tls_remote", "remote_x509_name", translate("Only accept connections from given X509 name") }, - { ListValue, "ns_cert_type", { "client", "server" }, translate("Require explicit designation on certificate") }, - { ListValue, "remote_cert_tls", { "client", "server" }, translate("Require explicit key usage on certificate") }, - { Value, "crl_verify", "/etc/easy-rsa/keys/crl.pem", translate("Check peer certificate against a CRL") }, - { Value, "tls_version_min", "1.0", translate("The lowest supported TLS version") }, - { Value, "tls_version_max", "1.2", translate("The highest supported TLS version") }, - { Value, "key_direction", "1", translate("The key direction for 'tls-auth' and 'secret' options") }, - } } + { FileUpload, + "secret", + "/etc/openvpn/secret.key", + translate("Enable Static Key encryption mode (non-TLS)") }, + -- parse + { Value, + "auth", + "SHA1", + translate("HMAC authentication for packets") }, + -- parse + { Value, + "cipher", + "BF-CBC", + translate("Encryption cipher for packets") }, + -- parse + { Value, + "keysize", + 1024, + translate("Size of cipher key") }, + -- parse + { Value, + "engine", + "dynamic", + translate("Enable OpenSSL hardware crypto engines") }, + { Flag, + "no_replay", + 0, + translate("Disable replay protection") }, + { Value, + "replay_window", + "64 15", + translate("Replay protection sliding window size") }, + { Flag, + "mute_replay_warnings", + 0, + translate("Silence the output of replay warnings") }, + { Value, + "replay_persist", + "/var/run/openvpn-replay-state", + translate("Persist replay-protection state") }, + { Flag, + "no_iv", + 0, + translate("Disable cipher initialisation vector") }, + { Flag, + "tls_server", + 0, + translate("Enable TLS and assume server role"), + { tls_client="" }, { tls_client="0" } }, + { Flag, + "tls_client", + 0, + translate("Enable TLS and assume client role"), + { tls_server="" }, { tls_server="0" } }, + { FileUpload, + "ca", + "/etc/easy-rsa/keys/ca.crt", + translate("Certificate authority") }, + { FileUpload, + "dh", + "/etc/easy-rsa/keys/dh1024.pem", + translate("Diffie Hellman parameters") }, + { FileUpload, + "cert", + "/etc/easy-rsa/keys/some-client.crt", + translate("Local certificate") }, + { FileUpload, + "key", + "/etc/easy-rsa/keys/some-client.key", + translate("Local private key") }, + { FileUpload, + "pkcs12", + "/etc/easy-rsa/keys/some-client.pk12", + translate("PKCS#12 file containing keys") }, + { ListValue, + "key_method", + { 1, 2 }, + translate("Enable TLS and assume client role") }, + { Value, + "tls_cipher", + "DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:AES256-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DES-CBC3-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:AES128-SHA:RC4-SHA:RC4-MD5:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DES-CBC-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-RC4-MD5", + translate("TLS cipher") }, + { Value, + "tls_timeout", + 2, + translate("Retransmit timeout on TLS control channel") }, + { Value, + "reneg_bytes", + 1024, + translate("Renegotiate data chan. key after bytes") }, + { Value, + "reneg_pkts", + 100, + translate("Renegotiate data chan. key after packets") }, + { Value, + "reneg_sec", + 3600, + translate("Renegotiate data chan. key after seconds") }, + { Value, + "hand_window", + 60, + translate("Timeframe for key exchange") }, + { Value, + "tran_window", + 3600, + translate("Key transition window") }, + { Flag, + "single_session", + 0, + translate("Allow only one session") }, + { Flag, + "tls_exit", + 0, + translate("Exit on TLS negotiation failure") }, + { Value, + "tls_auth", + "/etc/openvpn/tlsauth.key", + translate("Additional authentication over TLS") }, + -- { Value, + -- "askpass", + -- "[file]", + -- translate("Get PEM password from controlling tty before we daemonize") }, + { Flag, + "auth_nocache", + 0, + translate("Don't cache --askpass or --auth-user-pass passwords") }, + { Value, + "tls_remote", + "remote_x509_name", + translate("Only accept connections from given X509 name") }, + { ListValue, + "ns_cert_type", + { "client", "server" }, + translate("Require explicit designation on certificate") }, + { ListValue, + "remote_cert_tls", + { "client", "server" }, + translate("Require explicit key usage on certificate") }, + { Value, + "crl_verify", + "/etc/easy-rsa/keys/crl.pem", + translate("Check peer certificate against a CRL") }, + { Value, + "tls_version_min", + "1.0", + translate("The lowest supported TLS version") }, + { Value, + "tls_version_max", + "1.2", + translate("The highest supported TLS version") }, + { Value, + "key_direction", + "1", + translate("The key direction for 'tls-auth' and 'secret' options") }, + } } } diff --git a/applications/luci-app-simple-adblock/Makefile b/applications/luci-app-simple-adblock/Makefile new file mode 100644 index 0000000000..d7be6850ba --- /dev/null +++ b/applications/luci-app-simple-adblock/Makefile @@ -0,0 +1,16 @@ +# Copyright (c) 2017 Stan Grishin (stangri@melmac.net) +# This is free software, licensed under the GNU General Public License v3. + +include $(TOPDIR)/rules.mk + +PKG_LICENSE:=GPL-3.0+ +PKG_MAINTAINER:=Stan Grishin <stangri@melmac.net> + +LUCI_TITLE:=Simple Adblock Web UI +LUCI_DEPENDS:=+simple-adblock +LUCI_PKGARCH:=all +PKG_RELEASE:=2 + +include ../../luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/applications/luci-app-simple-adblock/luasrc/controller/simpleadblock.lua b/applications/luci-app-simple-adblock/luasrc/controller/simpleadblock.lua new file mode 100644 index 0000000000..46125b3098 --- /dev/null +++ b/applications/luci-app-simple-adblock/luasrc/controller/simpleadblock.lua @@ -0,0 +1,7 @@ +module("luci.controller.simpleadblock", package.seeall) +function index() + if not nixio.fs.access("/etc/config/simple-adblock") then + return + end + entry({"admin", "services", "simpleadblock"}, cbi("simpleadblock"), _("Simple AdBlock")) +end diff --git a/applications/luci-app-simple-adblock/luasrc/model/cbi/simpleadblock.lua b/applications/luci-app-simple-adblock/luasrc/model/cbi/simpleadblock.lua new file mode 100644 index 0000000000..214f298292 --- /dev/null +++ b/applications/luci-app-simple-adblock/luasrc/model/cbi/simpleadblock.lua @@ -0,0 +1,79 @@ +m = Map("simple-adblock", translate("Simple AdBlock Settings")) +s = m:section(NamedSection, "config", "simple-adblock") + +-- General options +e = s:option(Flag, "enabled", translate("Enable/start service")) +e.rmempty = false + +function e.cfgvalue(self, section) + return self.map:get(section, "enabled") == "1" and luci.sys.init.enabled("simple-adblock") and self.enabled or self.disabled +end + +function e.write(self, section, value) + if value == "1" then + luci.sys.call("/etc/init.d/simple-adblock enable >/dev/null") + luci.sys.call("/etc/init.d/simple-adblock start >/dev/null") + else + luci.sys.call("/etc/init.d/simple-adblock stop >/dev/null") + end + return Flag.write(self, section, value) +end + +o2 = s:option(ListValue, "verbosity", translate("Output Verbosity Setting"),translate("Controls system log and console output verbosity")) +o2:value("0", translate("Suppress output")) +o2:value("1", translate("Some output")) +o2:value("2", translate("Verbose output")) +o2.rmempty = false +o2.default = 2 + +o3 = s:option(ListValue, "force_dns", translate("Force Router DNS"), translate("Forces Router DNS use on local devices, also known as DNS Hijacking")) +o3:value("0", translate("Let local devices use their own DNS servers if set")) +o3:value("1", translate("Force Router DNS server to all local devices")) +o3.rmempty = false +o3.default = 1 + + +local sysfs_path = "/sys/class/leds/" +local leds = {} +if nixio.fs.access(sysfs_path) then + leds = nixio.util.consume((nixio.fs.dir(sysfs_path))) +end +if #leds ~= 0 then + o3 = s:option(Value, "led", translate("LED to indicate status"), translate("Pick the LED not already used in ") + .. [[<a href="]] .. luci.dispatcher.build_url("admin/system/leds") .. [[">]] + .. translate("System LED Configuration") .. [[</a>]]) + o3.rmempty = true + o3:value("", translate("none")) + for k, v in ipairs(leds) do + o3:value(v) + end +end + + +s2 = m:section(NamedSection, "config", "simple-adblock") +-- Whitelisted Domains +d1 = s2:option(DynamicList, "whitelist_domain", translate("Whitelisted Domains"), translate("Individual domains to be whitelisted")) +d1.addremove = false +d1.optional = false + +-- Blacklisted Domains +d3 = s2:option(DynamicList, "blacklist_domain", translate("Blacklisted Domains"), translate("Individual domains to be blacklisted")) +d3.addremove = false +d3.optional = false + +-- Whitelisted Domains URLs +d2 = s2:option(DynamicList, "whitelist_domains_url", translate("Whitelisted Domain URLs"), translate("URLs to lists of domains to be whitelisted")) +d2.addremove = false +d2.optional = false + +-- Blacklisted Domains URLs +d4 = s2:option(DynamicList, "blacklist_domains_url", translate("Blacklisted Domain URLs"), translate("URLs to lists of domains to be blacklisted")) +d4.addremove = false +d4.optional = false + +-- Blacklisted Hosts URLs +d5 = s2:option(DynamicList, "blacklist_hosts_url", translate("Blacklisted Hosts URLs"), translate("URLs to lists of hosts to be blacklisted")) +d5.addremove = false +d5.optional = false + +return m diff --git a/applications/luci-app-simple-adblock/po/ja/simple-adblock.po b/applications/luci-app-simple-adblock/po/ja/simple-adblock.po new file mode 100644 index 0000000000..ff75c8bf1d --- /dev/null +++ b/applications/luci-app-simple-adblock/po/ja/simple-adblock.po @@ -0,0 +1,91 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.12\n" +"Last-Translator: INAGAKI Hiroshi <musashino.open@gmail.com>\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"Language: ja\n" + +msgid "Blacklisted Domain URLs" +msgstr "ドメイン ブラックリストのURL" + +msgid "Blacklisted Domains" +msgstr "ブラックリスト ドメイン" + +msgid "Blacklisted Hosts URLs" +msgstr "hosts ブラックリストのURL" + +msgid "Controls system log and console output verbosity" +msgstr "システム ログとコンソール出力の冗長性を設定します。" + +msgid "Enable/start service" +msgstr "サービスの有効化/開始" + +msgid "Force Router DNS" +msgstr "ルーターDNSの強制" + +msgid "Force Router DNS server to all local devices" +msgstr "全ローカル デバイスにルーター DNSサーバーの使用を強制" + +msgid "Forces Router DNS use on local devices, also known as DNS Hijacking" +msgstr "ローカル デバイスに対し、ルーター上のDNSサーバーの使用を強制します。これは、DNS ハイジャックとしても知られています。" + +msgid "Individual domains to be blacklisted" +msgstr "ブラックリストに登録する、個々のドメインです。" + +msgid "Individual domains to be whitelisted" +msgstr "ホワイトリストに登録する、個々のドメインです。" + +msgid "LED to indicate status" +msgstr "ステータスを表示するLED" + +msgid "Let local devices use their own DNS servers if set" +msgstr "DNSサーバーの使用を強制しない" + +msgid "Output Verbosity Setting" +msgstr "出力詳細度の設定" + +msgid "Pick the LED not already used in" +msgstr "右の設定で既に使用されていないLEDを選択します:" + +msgid "Simple AdBlock" +msgstr "Simple AdBlock" + +msgid "Simple AdBlock Settings" +msgstr "Simple AdBlock 設定" + +msgid "Some output" +msgstr "軽量出力" + +msgid "Suppress output" +msgstr "出力の抑制" + +msgid "System LED Configuration" +msgstr "LED 設定" + +msgid "URLs to lists of domains to be blacklisted" +msgstr "ブラックリストに登録するドメインのリストのURLです。" + +msgid "URLs to lists of domains to be whitelisted" +msgstr "ホワイトリストに登録するドメインのリストのURLです。" + +msgid "URLs to lists of hosts to be blacklisted" +msgstr "ブラックリストに登録するドメインが列挙された、hostsファイルのURLです。" + +msgid "Verbose output" +msgstr "詳細出力" + +msgid "Whitelisted Domain URLs" +msgstr "ドメイン ホワイトリストのURL" + +msgid "Whitelisted Domains" +msgstr "ホワイトリスト ドメイン" + +msgid "none" +msgstr "なし" diff --git a/applications/luci-app-simple-adblock/po/templates/simple-adblock.pot b/applications/luci-app-simple-adblock/po/templates/simple-adblock.pot new file mode 100644 index 0000000000..4cfff964a3 --- /dev/null +++ b/applications/luci-app-simple-adblock/po/templates/simple-adblock.pot @@ -0,0 +1,80 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +msgid "Blacklisted Domain URLs" +msgstr "" + +msgid "Blacklisted Domains" +msgstr "" + +msgid "Blacklisted Hosts URLs" +msgstr "" + +msgid "Controls system log and console output verbosity" +msgstr "" + +msgid "Enable/start service" +msgstr "" + +msgid "Force Router DNS" +msgstr "" + +msgid "Force Router DNS server to all local devices" +msgstr "" + +msgid "Forces Router DNS use on local devices, also known as DNS Hijacking" +msgstr "" + +msgid "Individual domains to be blacklisted" +msgstr "" + +msgid "Individual domains to be whitelisted" +msgstr "" + +msgid "LED to indicate status" +msgstr "" + +msgid "Let local devices use their own DNS servers if set" +msgstr "" + +msgid "Output Verbosity Setting" +msgstr "" + +msgid "Pick the LED not already used in" +msgstr "" + +msgid "Simple AdBlock" +msgstr "" + +msgid "Simple AdBlock Settings" +msgstr "" + +msgid "Some output" +msgstr "" + +msgid "Suppress output" +msgstr "" + +msgid "System LED Configuration" +msgstr "" + +msgid "URLs to lists of domains to be blacklisted" +msgstr "" + +msgid "URLs to lists of domains to be whitelisted" +msgstr "" + +msgid "URLs to lists of hosts to be blacklisted" +msgstr "" + +msgid "Verbose output" +msgstr "" + +msgid "Whitelisted Domain URLs" +msgstr "" + +msgid "Whitelisted Domains" +msgstr "" + +msgid "none" +msgstr "" diff --git a/applications/luci-app-simple-adblock/root/etc/uci-defaults/40_luci-simple-adblock b/applications/luci-app-simple-adblock/root/etc/uci-defaults/40_luci-simple-adblock new file mode 100644 index 0000000000..3b7137e026 --- /dev/null +++ b/applications/luci-app-simple-adblock/root/etc/uci-defaults/40_luci-simple-adblock @@ -0,0 +1,10 @@ +#!/bin/sh +uci -q batch <<-EOF >/dev/null + delete ucitrack.@simple-adblock[-1] + add ucitrack simple-adblock + set ucitrack.@simple-adblock[-1].init=simple-adblock + commit ucitrack +EOF + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/applications/luci-app-vpnbypass/Makefile b/applications/luci-app-vpnbypass/Makefile index e26fe273cc..0ca74ae38a 100644 --- a/applications/luci-app-vpnbypass/Makefile +++ b/applications/luci-app-vpnbypass/Makefile @@ -9,7 +9,8 @@ PKG_MAINTAINER:=Stan Grishin <stangri@melmac.net> LUCI_TITLE:=VPN Bypass Web UI LUCI_DEPENDS:=+vpnbypass LUCI_PKGARCH:=all +PKG_RELEASE:=1 include ../../luci.mk -# call BuildPackage - OpenWrt buildroot signature
\ No newline at end of file +# call BuildPackage - OpenWrt buildroot signature diff --git a/applications/luci-app-vpnbypass/luasrc/model/cbi/vpnbypass.lua b/applications/luci-app-vpnbypass/luasrc/model/cbi/vpnbypass.lua index b505194638..b35a8e4e02 100644 --- a/applications/luci-app-vpnbypass/luasrc/model/cbi/vpnbypass.lua +++ b/applications/luci-app-vpnbypass/luasrc/model/cbi/vpnbypass.lua @@ -4,11 +4,11 @@ m = Map("vpnbypass", translate("VPN Bypass Settings")) s = m:section(NamedSection, "config", "vpnbypass") -- General options -e = s:option(Flag, "enabled", translate("Enable VPN Bypass")) +e = s:option(Flag, "enabled", translate("Enable/start service")) e.rmempty = false function e.cfgvalue(self, section) - return luci.sys.init.enabled("vpnbypass") and self.enabled or self.disabled + return self.map:get(section, "enabled") == "1" and luci.sys.init.enabled("vpnbypass") and self.enabled or self.disabled end function e.write(self, section, value) @@ -17,35 +17,35 @@ function e.write(self, section, value) luci.sys.call("/etc/init.d/vpnbypass start >/dev/null") else luci.sys.call("/etc/init.d/vpnbypass stop >/dev/null") - luci.sys.call("/etc/init.d/vpnbypass disable >/dev/null") end + return Flag.write(self, section, value) end -- Local Ports p1 = s:option(DynamicList, "localport", translate("Local Ports to Bypass"), translate("Local ports to trigger VPN Bypass")) p1.datatype = "portrange" -p1.placeholder = "0-65535" +-- p1.placeholder = "0-65535" p1.addremove = false p1.optional = false -- Remote Ports p2 = s:option(DynamicList, "remoteport", translate("Remote Ports to Bypass"), translate("Remote ports to trigger VPN Bypass")) p2.datatype = "portrange" -p2.placeholder = "0-65535" +-- p2.placeholder = "0-65535" p2.addremove = false p2.optional = false -- Local Subnets r1 = s:option(DynamicList, "localsubnet", translate("Local IP Addresses to Bypass"), translate("Local IP addresses or subnets with direct internet access (outside of the VPN tunnel)")) r1.datatype = "ip4addr" -r1.placeholder = luci.ip.new(uci.cursor():get("network", "lan", "ipaddr") .. "/" .. uci.cursor():get("network", "lan", "netmask")) +-- r1.placeholder = luci.ip.new(uci.cursor():get("network", "lan", "ipaddr") .. "/" .. uci.cursor():get("network", "lan", "netmask")) r1.addremove = false r1.optional = false -- Remote Subnets r2 = s:option(DynamicList, "remotesubnet", translate("Remote IP Addresses to Bypass"), translate("Remote IP addresses or subnets which will be accessed directly (outside of the VPN tunnel)")) r2.datatype = "ip4addr" -r2.placeholder = "0.0.0.0/0" +-- r2.placeholder = "0.0.0.0/0" r2.addremove = false r2.optional = false diff --git a/applications/luci-app-vpnbypass/po/templates/vpnbypass.pot b/applications/luci-app-vpnbypass/po/templates/vpnbypass.pot index 4322e19362..fd92b5e8a8 100644 --- a/applications/luci-app-vpnbypass/po/templates/vpnbypass.pot +++ b/applications/luci-app-vpnbypass/po/templates/vpnbypass.pot @@ -7,7 +7,7 @@ msgstr "" msgid "Domains to be accessed directly (outside of the VPN tunnel), see" msgstr "" -msgid "Enable VPN Bypass" +msgid "Enable/start service" msgstr "" msgid "Local IP Addresses to Bypass" |