diff options
Diffstat (limited to 'applications')
58 files changed, 5194 insertions, 188 deletions
diff --git a/applications/luci-app-adblock/Makefile b/applications/luci-app-adblock/Makefile index 8efe2d6048..614faf0e83 100644 --- a/applications/luci-app-adblock/Makefile +++ b/applications/luci-app-adblock/Makefile @@ -1,7 +1,6 @@ -# Copyright (C) 2016 Openwrt.org -# -# This is free software, licensed under the Apache License, Version 2.0 . -# +# Copyright 2016 Hannu Nyman +# Copyright 2017 Dirk Brenken (dev@brenken.org) +# This is free software, licensed under the Apache License, Version 2.0 include $(TOPDIR)/rules.mk @@ -11,4 +10,4 @@ LUCI_PKGARCH:=all include ../../luci.mk -# call BuildPackage - OpenWrt buildroot signature +# call BuildPackage - OpenWrt buildroot signature
\ No newline at end of file diff --git a/applications/luci-app-adblock/luasrc/controller/adblock.lua b/applications/luci-app-adblock/luasrc/controller/adblock.lua index d8b471814f..bcb2976033 100644 --- a/applications/luci-app-adblock/luasrc/controller/adblock.lua +++ b/applications/luci-app-adblock/luasrc/controller/adblock.lua @@ -1,12 +1,53 @@ --- Copyright 2016 Openwrt.org --- Licensed to the public under the Apache License 2.0. +-- Copyright 2016 Hannu Nyman +-- Copyright 2017 Dirk Brenken (dev@brenken.org) +-- This is free software, licensed under the Apache License, Version 2.0 module("luci.controller.adblock", package.seeall) +local fs = require("nixio.fs") +local util = require("luci.util") +local template = require("luci.template") +local i18n = require("luci.i18n") + function index() if not nixio.fs.access("/etc/config/adblock") then return end + entry({"admin", "services", "adblock"}, firstchild(), _("Adblock"), 30).dependent = false + entry({"admin", "services", "adblock", "tab_from_cbi"}, cbi("adblock/overview_tab"), _("Overview"), 10).leaf = true + entry({"admin", "services", "adblock", "logfile"}, call("logread"), _("View Logfile"), 20).leaf = true + entry({"admin", "services", "adblock", "advanced"}, firstchild(), _("Advanced"), 100) + entry({"admin", "services", "adblock", "advanced", "blacklist"}, cbi("adblock/blacklist_tab"), _("Edit Blacklist"), 110).leaf = true + entry({"admin", "services", "adblock", "advanced", "whitelist"}, cbi("adblock/whitelist_tab"), _("Edit Whitelist"), 120).leaf = true + entry({"admin", "services", "adblock", "advanced", "configuration"}, cbi("adblock/configuration_tab"), _("Edit Configuration"), 130).leaf = true + entry({"admin", "services", "adblock", "advanced", "query"}, call("query"), _("Query domains"), 140).leaf = true + entry({"admin", "services", "adblock", "advanced", "result"}, call("queryData"), nil, 150).leaf = true +end + +function logread() + local logfile = util.trim(util.exec("logread -e 'adblock'")) + template.render("adblock/logread", {title = i18n.translate("Adblock Logfile"), content = logfile}) +end - entry({"admin", "services", "adblock"}, cbi("adblock"), _("Adblock"), 40) +function query() + template.render("adblock/query", {title = i18n.translate("Adblock Domain Query")}) +end + +function queryData(domain) + if domain and domain:match("^[a-zA-Z0-9%-%._]+$") then + luci.http.prepare_content("text/plain") + local cmd = "/etc/init.d/adblock query %q 2>&1" + local util = io.popen(cmd % domain) + if util then + while true do + local line = util:read("*l") + if not line then + break + end + luci.http.write(line) + luci.http.write("\n") + end + util:close() + end + end end diff --git a/applications/luci-app-adblock/luasrc/model/cbi/adblock.lua b/applications/luci-app-adblock/luasrc/model/cbi/adblock.lua deleted file mode 100644 index 0a4a4cdd2f..0000000000 --- a/applications/luci-app-adblock/luasrc/model/cbi/adblock.lua +++ /dev/null @@ -1,63 +0,0 @@ --- Copyright 2016 Hannu Nyman --- Licensed to the public under the Apache License 2.0. - -m = Map("adblock", translate("Adblock"), - translate("Configuration of the adblock package to block ad/abuse domains by using DNS.")) - --- General options - -s = m:section(NamedSection, "global", "adblock", translate("Global options")) - -o1 = s:option(Flag, "adb_enabled", translate("Enable adblock")) -o1.rmempty = false -o1.default = 0 - -o3 = s:option(Value, "adb_whitelist", translate("Whitelist file"), - translate("File with whitelisted hosts/domains that are allowed despite being on a blocklist.")) -o3.rmempty = false -o3.datatype = "file" - --- Blocklist options - -bl = m:section(TypedSection, "source", translate("Blocklist sources"), - translate("Available blocklist sources (") - .. [[<a href="https://github.com/openwrt/packages/blob/master/net/adblock/files/README.md" target="_blank">]] - .. translate("see list details") - .. [[</a>]] - .. translate("). Note that list URLs and Shallalist category selections are not configurable via Luci.")) -bl.template = "cbi/tblsection" - -name = bl:option(Flag, "enabled", translate("Enabled")) -name.rmempty = false - -des = bl:option(DummyValue, "adb_src_desc", translate("Description")) - --- Additional options - -s2 = m:section(NamedSection, "global", "adblock", translate("Backup options")) - -o4 = s2:option(Flag, "adb_backup", translate("Enable blocklist backup")) -o4.rmempty = false -o4.default = 0 - -o5 = s2:option(Value, "adb_backupdir", translate("Backup directory")) -o5.rmempty = false -o5.datatype = "directory" - --- Extra options - -e = m:section(NamedSection, "global", "adblock", translate("Extra options"), - translate("Options for further tweaking in case the defaults are not suitable for you.")) - -a = e:option(Flag, "adb_debug", translate("Enable verbose debug logging")) -a.default = a.disabled -a.rmempty = false - -a = e:option(Value, "adb_iface", translate("Restrict reload trigger to certain interface(s)"), - translate("Space separated list of wan interfaces that trigger reload action. " .. - "To disable reload trigger set it to 'false'. Default: empty")) -a.datatype = "network" -a.rmempty = true - -return m - diff --git a/applications/luci-app-adblock/luasrc/model/cbi/adblock/blacklist_tab.lua b/applications/luci-app-adblock/luasrc/model/cbi/adblock/blacklist_tab.lua new file mode 100644 index 0000000000..efe40e09e5 --- /dev/null +++ b/applications/luci-app-adblock/luasrc/model/cbi/adblock/blacklist_tab.lua @@ -0,0 +1,39 @@ +-- Copyright 2016 Hannu Nyman +-- Copyright 2017 Dirk Brenken (dev@brenken.org) +-- This is free software, licensed under the Apache License, Version 2.0 + +local fs = require("nixio.fs") +local util = require("luci.util") +local uci = require("uci") +local adbinput = uci.get("adblock", "blacklist", "adb_src") + +if not nixio.fs.access(adbinput) then + m = SimpleForm("error", nil, translate("Input file not found, please check your configuration.")) + return m +end + +m = SimpleForm("input", nil) + m:append(Template("adblock/config_css")) + +s = m:section(SimpleSection, nil, + translatef("This form allows you to modify the content of the adblock blacklist (%s).<br />", adbinput) + .. translate("Please add only one domain per line. Comments introduced with '#' are allowed - ip addresses, wildcards and regex are not.")) + +f = s:option(TextValue, "data") + f.rmempty = true + f.datatype = "string" + f.rows = 20 + + function f.cfgvalue() + return nixio.fs.readfile(adbinput) or "" + end + + function f.write(self, section, data) + return nixio.fs.writefile(adbinput, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n") + end + + function s.handle(self, state, data) + return true + end + +return m diff --git a/applications/luci-app-adblock/luasrc/model/cbi/adblock/configuration_tab.lua b/applications/luci-app-adblock/luasrc/model/cbi/adblock/configuration_tab.lua new file mode 100644 index 0000000000..035b99e5e3 --- /dev/null +++ b/applications/luci-app-adblock/luasrc/model/cbi/adblock/configuration_tab.lua @@ -0,0 +1,36 @@ +-- Copyright 2016 Hannu Nyman +-- Copyright 2017 Dirk Brenken (dev@brenken.org) +-- This is free software, licensed under the Apache License, Version 2.0 + +local fs = require("nixio.fs") +local util = require("luci.util") +local adbinput = "/etc/config/adblock" + +if not nixio.fs.access(adbinput) then + m = SimpleForm("error", nil, translate("Input file not found, please check your configuration.")) + return m +end + +m = SimpleForm("input", nil) + m:append(Template("adblock/config_css")) + +s = m:section(SimpleSection, nil, +translate("This form allows you to modify the content of the main adblock configuration file (/etc/config/adblock).")) + +f = s:option(TextValue, "data") + f.rmempty = true + f.rows = 20 + + function f.cfgvalue() + return nixio.fs.readfile(adbinput) or "" + end + + function f.write(self, section, data) + return nixio.fs.writefile(adbinput, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n") + end + + function s.handle(self, state, data) + return true + end + +return m diff --git a/applications/luci-app-adblock/luasrc/model/cbi/adblock/overview_tab.lua b/applications/luci-app-adblock/luasrc/model/cbi/adblock/overview_tab.lua new file mode 100644 index 0000000000..b8318fe994 --- /dev/null +++ b/applications/luci-app-adblock/luasrc/model/cbi/adblock/overview_tab.lua @@ -0,0 +1,128 @@ +-- Copyright 2016 Hannu Nyman +-- Copyright 2017 Dirk Brenken (dev@brenken.org) +-- This is free software, licensed under the Apache License, Version 2.0 + +local sys = require("luci.sys") +local util = require("luci.util") +local data = util.ubus("service", "get_data", "name", "adblock") or { } +local dnsFile1 = sys.exec("find '/tmp/dnsmasq.d' -maxdepth 1 -type f -name 'adb_list*' -print 2>/dev/null") +local dnsFile2 = sys.exec("find '/var/lib/unbound' -maxdepth 1 -type f -name 'adb_list*' -print 2>/dev/null") + +m = Map("adblock", translate("Adblock"), + translate("Configuration of the adblock package to block ad/abuse domains by using DNS. ") + .. translate("For further information ") + .. [[<a href="https://github.com/openwrt/packages/blob/master/net/adblock/files/README.md" target="_blank">]] + .. translate("see online documentation") + .. [[</a>]] + .. translate(".")) + +-- Main adblock options + +s = m:section(NamedSection, "global", "adblock") + +o1 = s:option(Flag, "adb_enabled", translate("Enable adblock")) +o1.rmempty = false +o1.default = 0 + +btn = s:option(Button, "", translate("Suspend / Resume adblock")) +if data.adblock == nil then + btn.inputtitle = "n/a" + btn.inputstyle = nil + btn.disabled = true +elseif dnsFile1 ~= "" or dnsFile2 ~= "" then + btn.inputtitle = translate("Suspend adblock") + btn.inputstyle = "reset" + btn.disabled = false + function btn.write() + luci.sys.call("/etc/init.d/adblock suspend >/dev/null 2>&1") + end +else + btn.inputtitle = translate("Resume adblock") + btn.inputstyle = "apply" + btn.disabled = false + function btn.write() + luci.sys.call("/etc/init.d/adblock resume >/dev/null 2>&1") + end +end + +o2 = s:option(Flag, "adb_debug", translate("Enable verbose debug logging")) +o2.default = o2.disabled +o2.rmempty = false + +o3 = s:option(Value, "adb_iface", translate("Restrict interface reload trigger to certain interface(s)"), + translate("Space separated list of interfaces that trigger a reload action. ".. + "To disable reload trigger at all remove all entries.")) +o3.rmempty =true + +-- Runtime information + + ds = s:option(DummyValue, "_dummy", translate("Runtime information")) + ds.template = "cbi/nullsection" + + dv1 = s:option(DummyValue, "adblock_version", translate("Adblock version")) + dv1.template = "adblock/runtime" + if data.adblock ~= nil then + dv1.value = data.adblock.adblock.adblock_version or "n/a" + else + dv1.value = "n/a" + end + + dv2 = s:option(DummyValue, "status", translate("Status")) + dv2.template = "adblock/runtime" + if data.adblock == nil then + dv2.value = "n/a" + elseif dnsFile1 ~= "" or dnsFile2 ~= "" then + dv2.value = "active" + else + dv2.value = "suspended" + end + + dv3 = s:option(DummyValue, "dns_backend", translate("DNS backend")) + dv3.template = "adblock/runtime" + if data.adblock ~= nil then + dv3.value = data.adblock.adblock.dns_backend or "n/a" + else + dv3.value = "n/a" + end + + dv4 = s:option(DummyValue, "blocked_domains", translate("Blocked domains (overall)")) + dv4.template = "adblock/runtime" + if data.adblock ~= nil then + dv4.value = data.adblock.adblock.blocked_domains or "n/a" + else + dv4.value = "n/a" + end + + dv5 = s:option(DummyValue, "last_rundate", translate("Last rundate")) + dv5.template = "adblock/runtime" + if data.adblock ~= nil then + dv5.value = data.adblock.adblock.last_rundate or "n/a" + else + dv5.value = "n/a" + end + +-- Blocklist options + +bl = m:section(TypedSection, "source", translate("Blocklist sources"), + translate("Available blocklist sources. ") + .. translate("Note that list URLs and Shallalist category selections are configurable in the 'Advanced' section.")) +bl.template = "cbi/tblsection" + +name = bl:option(Flag, "enabled", translate("Enabled")) +name.rmempty = false + +des = bl:option(DummyValue, "adb_src_desc", translate("Description")) + +-- Backup options + +s = m:section(NamedSection, "global", "adblock", translate("Backup options")) + +o4 = s:option(Flag, "adb_backup", translate("Enable blocklist backup")) +o4.rmempty = false +o4.default = 0 + +o5 = s:option(Value, "adb_backupdir", translate("Backup directory")) +o5.rmempty = false +o5.datatype = "directory" + +return m diff --git a/applications/luci-app-adblock/luasrc/model/cbi/adblock/whitelist_tab.lua b/applications/luci-app-adblock/luasrc/model/cbi/adblock/whitelist_tab.lua new file mode 100644 index 0000000000..6c4dee4676 --- /dev/null +++ b/applications/luci-app-adblock/luasrc/model/cbi/adblock/whitelist_tab.lua @@ -0,0 +1,39 @@ +-- Copyright 2016 Hannu Nyman +-- Copyright 2017 Dirk Brenken (dev@brenken.org) +-- This is free software, licensed under the Apache License, Version 2.0 + +local fs = require("nixio.fs") +local util = require("luci.util") +local uci = require("uci") +local adbinput = uci.get("adblock", "global", "adb_whitelist") or " " + +if not nixio.fs.access(adbinput) then + m = SimpleForm("error", nil, translate("Input file not found, please check your configuration.")) + return m +end + +m = SimpleForm("input", nil) + m:append(Template("adblock/config_css")) + +s = m:section(SimpleSection, nil, + translatef("This form allows you to modify the content of the adblock whitelist (%s).<br />", adbinput) + .. translate("Please add only one domain per line. Comments introduced with '#' are allowed - ip addresses, wildcards and regex are not.")) + +f = s:option(TextValue, "data") + f.rmempty = true + f.datatype = "string" + f.rows = 20 + + function f.cfgvalue() + return nixio.fs.readfile(adbinput) or "" + end + + function f.write(self, section, data) + return nixio.fs.writefile(adbinput, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n") + end + + function s.handle(self, state, data) + return true + end + +return m diff --git a/applications/luci-app-adblock/luasrc/view/adblock/config_css.htm b/applications/luci-app-adblock/luasrc/view/adblock/config_css.htm new file mode 100644 index 0000000000..53493a18fb --- /dev/null +++ b/applications/luci-app-adblock/luasrc/view/adblock/config_css.htm @@ -0,0 +1,10 @@ +<style type="text/css"> + textarea + { + border: 1px solid #cccccc; + padding: 5px; + font-size: 12px; + font-family: monospace; + resize: none; + } +</style> diff --git a/applications/luci-app-adblock/luasrc/view/adblock/logread.htm b/applications/luci-app-adblock/luasrc/view/adblock/logread.htm new file mode 100644 index 0000000000..ce842a88e8 --- /dev/null +++ b/applications/luci-app-adblock/luasrc/view/adblock/logread.htm @@ -0,0 +1,15 @@ +<%# +Copyright 2016 Hannu Nyman +Copyright 2017 Dirk Brenken (dev@brenken.org) +This is free software, licensed under the Apache License, Version 2.0 +-%> + +<%+header%> + +<div class="cbi-map"> + <fieldset class="cbi-section"> + <div class="cbi-section-descr"><%:This form shows the syslog output, pre-filtered for adblock related messages only.%></div> + <textarea id="logread_id" style="width: 100%; height: 450px; border: 1px solid #cccccc; padding: 5px; font-size: 12px; font-family: monospace; resize: none;" readonly="readonly" wrap="off" rows="<%=content:cmatch("\n")+2%>"><%=content:pcdata()%></textarea> + </fieldset> +</div> +<%+footer%> diff --git a/applications/luci-app-adblock/luasrc/view/adblock/query.htm b/applications/luci-app-adblock/luasrc/view/adblock/query.htm new file mode 100644 index 0000000000..5e064af858 --- /dev/null +++ b/applications/luci-app-adblock/luasrc/view/adblock/query.htm @@ -0,0 +1,66 @@ +<%# +Copyright 2016 Hannu Nyman +Copyright 2017 Dirk Brenken (dev@brenken.org) +This is free software, licensed under the Apache License, Version 2.0 +-%> + +<%+header%> + +<script type="text/javascript" src="<%=resource%>/cbi.js"></script> +<script type="text/javascript"> +//<![CDATA[ + var stxhr = new XHR(); + + function update_status(data) + { + var domain = data.value; + var input = document.getElementById('query_input'); + var output = document.getElementById('query_output'); + + if (input && output) + { + output.innerHTML = + '<img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" /> ' + + '<%:Waiting for command to complete...%>' + ; + input.parentNode.style.display = 'block'; + input.style.display = 'inline'; + stxhr.post('<%=luci.dispatcher.build_url('admin/services/adblock/advanced/result/')%>' + domain, { token: '<%=token%>' }, + function(x) + { + if (x.responseText) + { + input.style.display = 'none'; + output.innerHTML = String.format('<pre>%h</pre>', x.responseText); + } + else + { + input.style.display = 'none'; + output.innerHTML = '<span class="error"><%:Invalid domain specified!%></span>'; + } + } + ); + } + } +//]]> +</script> + +<form method="post" action="<%=REQUEST_URI%>"> + <div class="cbi-map"> + <fieldset class="cbi-section"> + <div class="cbi-section-descr"><%:This form allows you to query active block lists for certain domains, e.g. for whitelisting.%></div> + <div style="width:33%; float:left;"> + <input style="margin: 5px 0" type="text" value="www.lede-project.org" name="input" /> + <input type="button" value="<%:Query%>" class="cbi-button cbi-button-apply" onclick="update_status(this.form.input)" /> + </div> + <br style="clear:both" /> + <br /> + </fieldset> + </div> + <fieldset class="cbi-section" style="display:none"> + <legend id="query_input"><%:Collecting data...%></legend> + <span id="query_output"></span> + </fieldset> +</form> + +<%+footer%> diff --git a/applications/luci-app-adblock/luasrc/view/adblock/runtime.htm b/applications/luci-app-adblock/luasrc/view/adblock/runtime.htm new file mode 100644 index 0000000000..4a90d41966 --- /dev/null +++ b/applications/luci-app-adblock/luasrc/view/adblock/runtime.htm @@ -0,0 +1,11 @@ +<%# +Copyright 2016 Hannu Nyman +Copyright 2017 Dirk Brenken (dev@brenken.org) +This is free software, licensed under the Apache License, Version 2.0 +-%> + +<%+cbi/valueheader%> + +<input name="runtime" id="runtime" type="text" class="cbi-input-text" style="border: none; box-shadow: none; background-color: #ffffff; color: #0069d6;" value="<%=self:cfgvalue(section)%>" disabled="disabled" /> + +<%+cbi/valuefooter%> diff --git a/applications/luci-app-adblock/po/ja/adblock.po b/applications/luci-app-adblock/po/ja/adblock.po index f436f5cc2b..d37fa748cb 100644 --- a/applications/luci-app-adblock/po/ja/adblock.po +++ b/applications/luci-app-adblock/po/ja/adblock.po @@ -8,21 +8,29 @@ msgstr "" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 1.8.12\n" +"X-Generator: Poedit 2.0\n" "Language: ja\n" -msgid "" -"). Note that list URLs and Shallalist category selections are not " -"configurable via Luci." -msgstr "" -")。これらのリストのURLおよびshallaリストの選択済みカテゴリーは、Luciを通して" -"設定することができません。" +msgid "." +msgstr "。" msgid "Adblock" msgstr "Adblock" -msgid "Available blocklist sources (" -msgstr "利用可能なブロックリスト提供元です(" +msgid "Adblock Domain Query" +msgstr "Adblock ドメイン検索" + +msgid "Adblock Logfile" +msgstr "Adblock ログファイル" + +msgid "Adblock version" +msgstr "Adblock バージョン" + +msgid "Advanced" +msgstr "詳細設定" + +msgid "Available blocklist sources." +msgstr "利用可能なブロックリスト提供元です。" msgid "Backup directory" msgstr "バックアップ先 ディレクトリ" @@ -30,20 +38,38 @@ msgstr "バックアップ先 ディレクトリ" msgid "Backup options" msgstr "バックアップ オプション" +msgid "Blocked domains (overall)" +msgstr "ブロック済みドメイン(全体)" + msgid "Blocklist sources" msgstr "ブロックリスト提供元" +msgid "Collecting data..." +msgstr "データ収集中です..." + msgid "" "Configuration of the adblock package to block ad/abuse domains by using DNS." msgstr "" -"DNSの利用によって広告/不正ドメインをブロックする、adblock パッケージの設定で" +"DNS の利用によって広告/不正ドメインをブロックする、Adblock パッケージの設定で" "す。" +msgid "DNS backend" +msgstr "DNS バックエンド" + msgid "Description" msgstr "説明" +msgid "Edit Blacklist" +msgstr "ブラックリストの編集" + +msgid "Edit Configuration" +msgstr "設定の編集" + +msgid "Edit Whitelist" +msgstr "ホワイトリストの編集" + msgid "Enable adblock" -msgstr "adblockの有効化" +msgstr "Adblock の有効化" msgid "Enable blocklist backup" msgstr "ブロックリスト バックアップの有効化" @@ -54,38 +80,174 @@ msgstr "詳細なデバッグ ログの有効化" msgid "Enabled" msgstr "有効" -msgid "Extra options" -msgstr "拡張設定" +msgid "For further information" +msgstr "詳細な情報は" + +msgid "Input file not found, please check your configuration." +msgstr "入力ファイルが見つかりません。設定を確認してください。" + +msgid "Invalid domain specified!" +msgstr "無効なドメインが指定されています!" + +msgid "Last rundate" +msgstr "最終実行日時" + +msgid "Loading" +msgstr "読込中" + +msgid "" +"Note that list URLs and Shallalist category selections are configurable in " +"the 'Advanced' section." +msgstr "" +"リストの URL 及び \"Shalla\" リストのカテゴリー設定は、'詳細設定' セクション" +"で設定することができます。" + +msgid "Overview" +msgstr "概要" + +msgid "" +"Please add only one domain per line. Comments introduced with '#' are " +"allowed - ip addresses, wildcards and regex are not." +msgstr "" +"1行に1つのドメインを追加してください。'#' から始まるコメントを記述できます" +"が、IP アドレスやワイルドカード、正規表現を設定値として使用することはできませ" +"ん。" + +msgid "Query" +msgstr "検索" + +msgid "Query domains" +msgstr "ドメインの検索" + +msgid "Restrict interface reload trigger to certain interface(s)" +msgstr "リロード トリガを特定のインターフェースに限定する" + +msgid "Resume adblock" +msgstr "Adblock の再開" + +msgid "Runtime information" +msgstr "実行情報" + +msgid "" +"Space separated list of interfaces that trigger a reload action. To disable " +"reload trigger at all remove all entries." +msgstr "" +"リロードのトリガとなる、スペースで区切られたインターフェースのリストです。リ" +"ロード トリガを無効にするには、全てのエントリーを削除して空欄にします。" + +msgid "Status" +msgstr "ステータス" + +msgid "Suspend / Resume adblock" +msgstr "Adblock の一時停止/再開" + +msgid "Suspend adblock" +msgstr "Adblock の一時停止" msgid "" -"File with whitelisted hosts/domains that are allowed despite being on a " -"blocklist." +"This form allows you to modify the content of the adblock blacklist (%s)." +"<br />" msgstr "" -"ホワイトリスト ファイル内のホスト/ドメインは、ブロックリストの登録に関わらず" -"許可されます。" +"このフォームでは、Adblock ブラックリスト (%s) の内容を変更することができま" +"す。<br />" -msgid "Global options" -msgstr "一般設定" +msgid "" +"This form allows you to modify the content of the adblock whitelist (%s)." +"<br />" +msgstr "" +"このフォームでは、Adblock ホワイトリスト (%s) の内容を変更することができま" +"す。<br />" msgid "" -"Options for further tweaking in case the defaults are not suitable for you." -msgstr "デフォルト設定が適切でない場合、追加で設定するためのオプションです。" +"This form allows you to modify the content of the main adblock configuration " +"file (/etc/config/adblock)." +msgstr "" +"このフォームでは、メインのAdblock 設定ファイル (/etc/config/adblock) の内容を" +"変更することができます。" -msgid "Restrict reload trigger to certain interface(s)" -msgstr "リロードトリガを特定のインターフェースに限定する" +msgid "" +"This form allows you to query active block lists for certain domains, e.g. " +"for whitelisting." +msgstr "" +"このフォームでは、現在有効なリスト内で特定のドメインを検索することができま" +"す。例: ホワイトリスト内" msgid "" -"Space separated list of wan interfaces that trigger reload action. To " -"disable reload trigger set it to 'false'. Default: empty" +"This form shows the syslog output, pre-filtered for adblock related messages " +"only." msgstr "" -"リロード実行のトリガとなる、スペースで区切られたWANインターフェースのリストで" -"す。リロードトリガを無効にするには、 false を設定します。デフォルト:(空)" +"このフォームには、システムログ内の Adblock に関連するメッセージのみが表示され" +"ます。" + +msgid "View Logfile" +msgstr "ログファイルを見る" + +msgid "Waiting for command to complete..." +msgstr "コマンドの完了をお待ちください..." + +msgid "see online documentation" +msgstr "オンライン ドキュメントを確認してください" + +#~ msgid "" +#~ "Space separated list of interfaces that trigger a reload action. To " +#~ "disable reload trigger at all set it to 'false'." +#~ msgstr "" +#~ "リロードのトリガとなる、スペースで区切られたインターフェースのリストで" +#~ "す。'false' に設定した場合、全てのリロード トリガは無効になります。" + +#~ msgid "" +#~ "Please add only one domain per line. Comments introduced with '#' are " +#~ "allowed - ip addresses, wildcards & regex are not." +#~ msgstr "" +#~ "一行に一つのドメインを追加してください。'#' から始まるコメントを記述できま" +#~ "すが、IPアドレスやワイルドカード、正規表現を設定値として使用することはでき" +#~ "ません。" + +#~ msgid "" +#~ "). Note that list URLs and Shallalist category selections are not " +#~ "configurable via Luci." +#~ msgstr "" +#~ ")。これらのリストのURLおよびshallaリストの選択済みカテゴリーは、Luciを通" +#~ "して設定することができません。" + +#~ msgid "Available blocklist sources (" +#~ msgstr "利用可能なブロックリスト提供元です(" + +#~ msgid "Extra options" +#~ msgstr "拡張設定" + +#~ msgid "" +#~ "File with whitelisted hosts/domains that are allowed despite being on a " +#~ "blocklist." +#~ msgstr "" +#~ "ホワイトリスト ファイル内のホスト/ドメインは、ブロックリストの登録に関わら" +#~ "ず許可されます。" + +#~ msgid "Global options" +#~ msgstr "一般設定" + +#~ msgid "" +#~ "Options for further tweaking in case the defaults are not suitable for " +#~ "you." +#~ msgstr "" +#~ "デフォルト設定が適切でない場合、追加で設定するためのオプションです。" + +#~ msgid "Restrict reload trigger to certain interface(s)" +#~ msgstr "リロードトリガを特定のインターフェースに限定する" + +#~ msgid "" +#~ "Space separated list of wan interfaces that trigger reload action. To " +#~ "disable reload trigger set it to 'false'. Default: empty" +#~ msgstr "" +#~ "リロード実行のトリガとなる、スペースで区切られたWANインターフェースのリス" +#~ "トです。リロードトリガを無効にするには、 false を設定します。デフォルト:" +#~ "(空)" -msgid "Whitelist file" -msgstr "ホワイトリスト ファイル" +#~ msgid "Whitelist file" +#~ msgstr "ホワイトリスト ファイル" -msgid "see list details" -msgstr "リストの詳細を見る" +#~ msgid "see list details" +#~ msgstr "リストの詳細を見る" #~ msgid "Count" #~ msgstr "カウント" diff --git a/applications/luci-app-adblock/po/pt-br/adblock.po b/applications/luci-app-adblock/po/pt-br/adblock.po index a238dc7f94..32553277b2 100644 --- a/applications/luci-app-adblock/po/pt-br/adblock.po +++ b/applications/luci-app-adblock/po/pt-br/adblock.po @@ -12,18 +12,26 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "Language: pt_BR\n" -msgid "" -"). Note that list URLs and Shallalist category selections are not " -"configurable via Luci." +msgid "." msgstr "" -"). Note que a lista de URL e as seleções de categoria da Shallalist não são " -"configuráveis pelo Luci." msgid "Adblock" msgstr "Adblock" -msgid "Available blocklist sources (" -msgstr "Fontes de listas de bloqueio disponíveis (" +msgid "Adblock Domain Query" +msgstr "" + +msgid "Adblock Logfile" +msgstr "" + +msgid "Adblock version" +msgstr "" + +msgid "Advanced" +msgstr "" + +msgid "Available blocklist sources." +msgstr "" msgid "Backup directory" msgstr "Diretório da cópia de segurança" @@ -31,18 +39,36 @@ msgstr "Diretório da cópia de segurança" msgid "Backup options" msgstr "Opções da cópia de segurança" +msgid "Blocked domains (overall)" +msgstr "" + msgid "Blocklist sources" msgstr "Fontes de listas de bloqueio" +msgid "Collecting data..." +msgstr "" + msgid "" "Configuration of the adblock package to block ad/abuse domains by using DNS." msgstr "" "Configuração do pacote adblock para bloquear, usando o DNS, domínios que " "distribuem propagandas abusivas." +msgid "DNS backend" +msgstr "" + msgid "Description" msgstr "Descrição" +msgid "Edit Blacklist" +msgstr "" + +msgid "Edit Configuration" +msgstr "" + +msgid "Edit Whitelist" +msgstr "" + msgid "Enable adblock" msgstr "Habilitar adblock" @@ -55,38 +81,140 @@ msgstr "Habilite registros detalhados para depuração" msgid "Enabled" msgstr "Habilitado" -msgid "Extra options" -msgstr "Opções adicionais" +msgid "For further information" +msgstr "" + +msgid "Input file not found, please check your configuration." +msgstr "" + +msgid "Invalid domain specified!" +msgstr "" + +msgid "Last rundate" +msgstr "" + +msgid "Loading" +msgstr "" msgid "" -"File with whitelisted hosts/domains that are allowed despite being on a " -"blocklist." +"Note that list URLs and Shallalist category selections are configurable in " +"the 'Advanced' section." msgstr "" -"Arquivo com a lista branca dos equipamentos/domínios que serão autorizados " -"mesmo estando na lista de bloqueio." -msgid "Global options" -msgstr "Opções Globais" +msgid "Overview" +msgstr "" msgid "" -"Options for further tweaking in case the defaults are not suitable for you." +"Please add only one domain per line. Comments introduced with '#' are " +"allowed - ip addresses, wildcards and regex are not." msgstr "" -"Opções para aprimoramentos adicionais caso as opções padrão não sejam " -"suficientes para você." -msgid "Restrict reload trigger to certain interface(s)" -msgstr "Restringir o gatilho de recarga para somente alguma(s) interface(s)" +msgid "Query" +msgstr "" + +msgid "Query domains" +msgstr "" + +msgid "Restrict interface reload trigger to certain interface(s)" +msgstr "" + +msgid "Resume adblock" +msgstr "" + +msgid "Runtime information" +msgstr "" msgid "" -"Space separated list of wan interfaces that trigger reload action. To " -"disable reload trigger set it to 'false'. Default: empty" +"Space separated list of interfaces that trigger a reload action. To disable " +"reload trigger at all remove all entries." +msgstr "" + +msgid "Status" msgstr "" -"Lista das interfaces WAN, separadas por espaço, que podem disparar uma ação " -"de recarga. Para desabilitar este gatilho, defina-o como 'false'. Padrão: em " -"branco" -msgid "Whitelist file" -msgstr "Arquivo da lista branca" +msgid "Suspend / Resume adblock" +msgstr "" + +msgid "Suspend adblock" +msgstr "" + +msgid "" +"This form allows you to modify the content of the adblock blacklist (%s)." +"<br />" +msgstr "" + +msgid "" +"This form allows you to modify the content of the adblock whitelist (%s)." +"<br />" +msgstr "" + +msgid "" +"This form allows you to modify the content of the main adblock configuration " +"file (/etc/config/adblock)." +msgstr "" + +msgid "" +"This form allows you to query active block lists for certain domains, e.g. " +"for whitelisting." +msgstr "" + +msgid "" +"This form shows the syslog output, pre-filtered for adblock related messages " +"only." +msgstr "" + +msgid "View Logfile" +msgstr "" + +msgid "Waiting for command to complete..." +msgstr "" + +msgid "see online documentation" +msgstr "" -msgid "see list details" -msgstr "veja os detalhes da lista" +#~ msgid "" +#~ "). Note that list URLs and Shallalist category selections are not " +#~ "configurable via Luci." +#~ msgstr "" +#~ "). Note que a lista de URL e as seleções de categoria da Shallalist não " +#~ "são configuráveis pelo Luci." + +#~ msgid "Available blocklist sources (" +#~ msgstr "Fontes de listas de bloqueio disponíveis (" + +#~ msgid "Extra options" +#~ msgstr "Opções adicionais" + +#~ msgid "" +#~ "File with whitelisted hosts/domains that are allowed despite being on a " +#~ "blocklist." +#~ msgstr "" +#~ "Arquivo com a lista branca dos equipamentos/domínios que serão " +#~ "autorizados mesmo estando na lista de bloqueio." + +#~ msgid "Global options" +#~ msgstr "Opções Globais" + +#~ msgid "" +#~ "Options for further tweaking in case the defaults are not suitable for " +#~ "you." +#~ msgstr "" +#~ "Opções para aprimoramentos adicionais caso as opções padrão não sejam " +#~ "suficientes para você." + +#~ msgid "Restrict reload trigger to certain interface(s)" +#~ msgstr "Restringir o gatilho de recarga para somente alguma(s) interface(s)" + +#~ msgid "" +#~ "Space separated list of wan interfaces that trigger reload action. To " +#~ "disable reload trigger set it to 'false'. Default: empty" +#~ msgstr "" +#~ "Lista das interfaces WAN, separadas por espaço, que podem disparar uma " +#~ "ação de recarga. Para desabilitar este gatilho, defina-o como 'false'. " +#~ "Padrão: em branco" + +#~ msgid "Whitelist file" +#~ msgstr "Arquivo da lista branca" + +#~ msgid "see list details" +#~ msgstr "veja os detalhes da lista" diff --git a/applications/luci-app-adblock/po/sv/adblock.po b/applications/luci-app-adblock/po/sv/adblock.po index 22a30e9a10..0e2f039de7 100644 --- a/applications/luci-app-adblock/po/sv/adblock.po +++ b/applications/luci-app-adblock/po/sv/adblock.po @@ -1,16 +1,26 @@ msgid "" msgstr "Content-Type: text/plain; charset=UTF-8\n" -msgid "" -"). Note that list URLs and Shallalist category selections are not " -"configurable via Luci." +msgid "." msgstr "" msgid "Adblock" msgstr "Blockering av annonser" -msgid "Available blocklist sources (" -msgstr "Tillgängliga källor för blockeringslistor (" +msgid "Adblock Domain Query" +msgstr "" + +msgid "Adblock Logfile" +msgstr "" + +msgid "Adblock version" +msgstr "" + +msgid "Advanced" +msgstr "" + +msgid "Available blocklist sources." +msgstr "" msgid "Backup directory" msgstr "Säkerhetskopiera mapp" @@ -18,18 +28,36 @@ msgstr "Säkerhetskopiera mapp" msgid "Backup options" msgstr "Alternativ för säkerhetskopiering" +msgid "Blocked domains (overall)" +msgstr "" + msgid "Blocklist sources" msgstr "Källor för blockeringslistor" +msgid "Collecting data..." +msgstr "" + msgid "" "Configuration of the adblock package to block ad/abuse domains by using DNS." msgstr "" "Konfiguration av paket adblock för att blockera annons/otillåtna domäner " "genom att användning DNS." +msgid "DNS backend" +msgstr "" + msgid "Description" msgstr "Beskrivning" +msgid "Edit Blacklist" +msgstr "" + +msgid "Edit Configuration" +msgstr "" + +msgid "Edit Whitelist" +msgstr "" + msgid "Enable adblock" msgstr "Aktivera abblock" @@ -42,34 +70,111 @@ msgstr "" msgid "Enabled" msgstr "Aktiverad" -msgid "Extra options" -msgstr "Extra alternativ" +msgid "For further information" +msgstr "" + +msgid "Input file not found, please check your configuration." +msgstr "" + +msgid "Invalid domain specified!" +msgstr "" + +msgid "Last rundate" +msgstr "" + +msgid "Loading" +msgstr "" + +msgid "" +"Note that list URLs and Shallalist category selections are configurable in " +"the 'Advanced' section." +msgstr "" + +msgid "Overview" +msgstr "" msgid "" -"File with whitelisted hosts/domains that are allowed despite being on a " -"blocklist." +"Please add only one domain per line. Comments introduced with '#' are " +"allowed - ip addresses, wildcards and regex are not." +msgstr "" + +msgid "Query" +msgstr "" + +msgid "Query domains" +msgstr "" + +msgid "Restrict interface reload trigger to certain interface(s)" +msgstr "" + +msgid "Resume adblock" msgstr "" -msgid "Global options" -msgstr "Globala alternativ" +msgid "Runtime information" +msgstr "" msgid "" -"Options for further tweaking in case the defaults are not suitable for you." +"Space separated list of interfaces that trigger a reload action. To disable " +"reload trigger at all remove all entries." +msgstr "" + +msgid "Status" +msgstr "" + +msgid "Suspend / Resume adblock" msgstr "" -msgid "Restrict reload trigger to certain interface(s)" +msgid "Suspend adblock" msgstr "" msgid "" -"Space separated list of wan interfaces that trigger reload action. To " -"disable reload trigger set it to 'false'. Default: empty" +"This form allows you to modify the content of the adblock blacklist (%s)." +"<br />" msgstr "" -msgid "Whitelist file" -msgstr "Vitlista fil" +msgid "" +"This form allows you to modify the content of the adblock whitelist (%s)." +"<br />" +msgstr "" + +msgid "" +"This form allows you to modify the content of the main adblock configuration " +"file (/etc/config/adblock)." +msgstr "" + +msgid "" +"This form allows you to query active block lists for certain domains, e.g. " +"for whitelisting." +msgstr "" + +msgid "" +"This form shows the syslog output, pre-filtered for adblock related messages " +"only." +msgstr "" + +msgid "View Logfile" +msgstr "" + +msgid "Waiting for command to complete..." +msgstr "" + +msgid "see online documentation" +msgstr "" + +#~ msgid "Available blocklist sources (" +#~ msgstr "Tillgängliga källor för blockeringslistor (" + +#~ msgid "Extra options" +#~ msgstr "Extra alternativ" + +#~ msgid "Global options" +#~ msgstr "Globala alternativ" + +#~ msgid "Whitelist file" +#~ msgstr "Vitlista fil" -msgid "see list details" -msgstr "se listans detaljer" +#~ msgid "see list details" +#~ msgstr "se listans detaljer" #~ msgid "Count" #~ msgstr "Räkna" diff --git a/applications/luci-app-adblock/po/templates/adblock.pot b/applications/luci-app-adblock/po/templates/adblock.pot index 6b2dbd13b3..464ffd9949 100644 --- a/applications/luci-app-adblock/po/templates/adblock.pot +++ b/applications/luci-app-adblock/po/templates/adblock.pot @@ -1,15 +1,25 @@ msgid "" msgstr "Content-Type: text/plain; charset=UTF-8" -msgid "" -"). Note that list URLs and Shallalist category selections are not " -"configurable via Luci." +msgid "." msgstr "" msgid "Adblock" msgstr "" -msgid "Available blocklist sources (" +msgid "Adblock Domain Query" +msgstr "" + +msgid "Adblock Logfile" +msgstr "" + +msgid "Adblock version" +msgstr "" + +msgid "Advanced" +msgstr "" + +msgid "Available blocklist sources." msgstr "" msgid "Backup directory" @@ -18,16 +28,34 @@ msgstr "" msgid "Backup options" msgstr "" +msgid "Blocked domains (overall)" +msgstr "" + msgid "Blocklist sources" msgstr "" +msgid "Collecting data..." +msgstr "" + msgid "" "Configuration of the adblock package to block ad/abuse domains by using DNS." msgstr "" +msgid "DNS backend" +msgstr "" + msgid "Description" msgstr "" +msgid "Edit Blacklist" +msgstr "" + +msgid "Edit Configuration" +msgstr "" + +msgid "Edit Whitelist" +msgstr "" + msgid "Enable adblock" msgstr "" @@ -40,31 +68,93 @@ msgstr "" msgid "Enabled" msgstr "" -msgid "Extra options" +msgid "For further information" +msgstr "" + +msgid "Input file not found, please check your configuration." +msgstr "" + +msgid "Invalid domain specified!" +msgstr "" + +msgid "Last rundate" +msgstr "" + +msgid "Loading" +msgstr "" + +msgid "" +"Note that list URLs and Shallalist category selections are configurable in " +"the 'Advanced' section." +msgstr "" + +msgid "Overview" +msgstr "" + +msgid "" +"Please add only one domain per line. Comments introduced with '#' are " +"allowed - ip addresses, wildcards and regex are not." +msgstr "" + +msgid "Query" +msgstr "" + +msgid "Query domains" +msgstr "" + +msgid "Restrict interface reload trigger to certain interface(s)" +msgstr "" + +msgid "Resume adblock" +msgstr "" + +msgid "Runtime information" msgstr "" msgid "" -"File with whitelisted hosts/domains that are allowed despite being on a " -"blocklist." +"Space separated list of interfaces that trigger a reload action. To disable " +"reload trigger at all remove all entries." +msgstr "" + +msgid "Status" msgstr "" -msgid "Global options" +msgid "Suspend / Resume adblock" +msgstr "" + +msgid "Suspend adblock" msgstr "" msgid "" -"Options for further tweaking in case the defaults are not suitable for you." +"This form allows you to modify the content of the adblock blacklist (%s)." +"<br />" msgstr "" -msgid "Restrict reload trigger to certain interface(s)" +msgid "" +"This form allows you to modify the content of the adblock whitelist (%s)." +"<br />" msgstr "" msgid "" -"Space separated list of wan interfaces that trigger reload action. To " -"disable reload trigger set it to 'false'. Default: empty" +"This form allows you to modify the content of the main adblock configuration " +"file (/etc/config/adblock)." +msgstr "" + +msgid "" +"This form allows you to query active block lists for certain domains, e.g. " +"for whitelisting." +msgstr "" + +msgid "" +"This form shows the syslog output, pre-filtered for adblock related messages " +"only." +msgstr "" + +msgid "View Logfile" msgstr "" -msgid "Whitelist file" +msgid "Waiting for command to complete..." msgstr "" -msgid "see list details" +msgid "see online documentation" msgstr "" diff --git a/applications/luci-app-adblock/po/zh-cn/adblock.po b/applications/luci-app-adblock/po/zh-cn/adblock.po index 2878d8afaf..36af78bdab 100644 --- a/applications/luci-app-adblock/po/zh-cn/adblock.po +++ b/applications/luci-app-adblock/po/zh-cn/adblock.po @@ -12,16 +12,26 @@ msgstr "" "X-Generator: Poedit 1.8.5\n" "Plural-Forms: nplurals=1; plural=0;\n" -msgid "" -"). Note that list URLs and Shallalist category selections are not " -"configurable via Luci." -msgstr ")。需要注意的是列表URL和列表类别选项无法通过Luci设置。" +msgid "." +msgstr "" msgid "Adblock" msgstr "Adblock" -msgid "Available blocklist sources (" -msgstr "可用拦截列表来源(" +msgid "Adblock Domain Query" +msgstr "" + +msgid "Adblock Logfile" +msgstr "" + +msgid "Adblock version" +msgstr "" + +msgid "Advanced" +msgstr "" + +msgid "Available blocklist sources." +msgstr "" msgid "Backup directory" msgstr "备份目录" @@ -29,16 +39,34 @@ msgstr "备份目录" msgid "Backup options" msgstr "备份选项" +msgid "Blocked domains (overall)" +msgstr "" + msgid "Blocklist sources" msgstr "拦截列表来源" +msgid "Collecting data..." +msgstr "" + msgid "" "Configuration of the adblock package to block ad/abuse domains by using DNS." msgstr "Adblock 配置工具,通过 DNS 来拦截广告和阻止域名。" +msgid "DNS backend" +msgstr "" + msgid "Description" msgstr "描述" +msgid "Edit Blacklist" +msgstr "" + +msgid "Edit Configuration" +msgstr "" + +msgid "Edit Whitelist" +msgstr "" + msgid "Enable adblock" msgstr "启用Adblock" @@ -51,34 +79,126 @@ msgstr "" msgid "Enabled" msgstr "启用" -msgid "Extra options" -msgstr "额外选项" +msgid "For further information" +msgstr "" + +msgid "Input file not found, please check your configuration." +msgstr "" + +msgid "Invalid domain specified!" +msgstr "" + +msgid "Last rundate" +msgstr "" + +msgid "Loading" +msgstr "" msgid "" -"File with whitelisted hosts/domains that are allowed despite being on a " -"blocklist." -msgstr "允许的主机/域名列表" +"Note that list URLs and Shallalist category selections are configurable in " +"the 'Advanced' section." +msgstr "" -msgid "Global options" -msgstr "全局选项" +msgid "Overview" +msgstr "" msgid "" -"Options for further tweaking in case the defaults are not suitable for you." -msgstr "在默认设置并不适合你时的额外选项。" +"Please add only one domain per line. Comments introduced with '#' are " +"allowed - ip addresses, wildcards and regex are not." +msgstr "" -msgid "Restrict reload trigger to certain interface(s)" +msgid "Query" +msgstr "" + +msgid "Query domains" +msgstr "" + +msgid "Restrict interface reload trigger to certain interface(s)" +msgstr "" + +msgid "Resume adblock" +msgstr "" + +msgid "Runtime information" +msgstr "" + +msgid "" +"Space separated list of interfaces that trigger a reload action. To disable " +"reload trigger at all remove all entries." +msgstr "" + +msgid "Status" +msgstr "" + +msgid "Suspend / Resume adblock" +msgstr "" + +msgid "Suspend adblock" +msgstr "" + +msgid "" +"This form allows you to modify the content of the adblock blacklist (%s)." +"<br />" msgstr "" msgid "" -"Space separated list of wan interfaces that trigger reload action. To " -"disable reload trigger set it to 'false'. Default: empty" +"This form allows you to modify the content of the adblock whitelist (%s)." +"<br />" msgstr "" -msgid "Whitelist file" -msgstr "白名单文件" +msgid "" +"This form allows you to modify the content of the main adblock configuration " +"file (/etc/config/adblock)." +msgstr "" + +msgid "" +"This form allows you to query active block lists for certain domains, e.g. " +"for whitelisting." +msgstr "" + +msgid "" +"This form shows the syslog output, pre-filtered for adblock related messages " +"only." +msgstr "" + +msgid "View Logfile" +msgstr "" + +msgid "Waiting for command to complete..." +msgstr "" + +msgid "see online documentation" +msgstr "" + +#~ msgid "" +#~ "). Note that list URLs and Shallalist category selections are not " +#~ "configurable via Luci." +#~ msgstr ")。需要注意的是列表URL和列表类别选项无法通过Luci设置。" + +#~ msgid "Available blocklist sources (" +#~ msgstr "可用拦截列表来源(" + +#~ msgid "Extra options" +#~ msgstr "额外选项" + +#~ msgid "" +#~ "File with whitelisted hosts/domains that are allowed despite being on a " +#~ "blocklist." +#~ msgstr "允许的主机/域名列表" + +#~ msgid "Global options" +#~ msgstr "全局选项" + +#~ msgid "" +#~ "Options for further tweaking in case the defaults are not suitable for " +#~ "you." +#~ msgstr "在默认设置并不适合你时的额外选项。" + +#~ msgid "Whitelist file" +#~ msgstr "白名单文件" -msgid "see list details" -msgstr "查看列表详情" +#~ msgid "see list details" +#~ msgstr "查看列表详情" #~ msgid "Count" #~ msgstr "数量" 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-mwan3/Makefile b/applications/luci-app-mwan3/Makefile new file mode 100644 index 0000000000..d65cd3af16 --- /dev/null +++ b/applications/luci-app-mwan3/Makefile @@ -0,0 +1,19 @@ +# +# 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> \ + Florian Eckert <fe@dev.tdt.de> + +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..e81ef74d2a --- /dev/null +++ b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/interfaceconfig.lua @@ -0,0 +1,250 @@ +-- ------ 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")) + +family = mwan_interface:option(ListValue, "family", translate("Internet Protocol")) + family.default = "ipv4" + family:value("ipv4", translate("IPv4")) + family:value("ipv6", translate("IPv6")) + +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") + +size = mwan_interface:option(Value, "size", translate("Ping size")) + size.default = "56" + size:value("8") + size:value("24") + size:value("56") + size:value("120") + size:value("248") + size:value("504") + size:value("1016") + size:value("1472") + size:value("2040") + size.datatype = "range(1, 65507)" + size.rmempty = false + size.optional = false + +timeout = mwan_interface:option(ListValue, "timeout", translate("Ping timeout")) + timeout.default = "2" + timeout:value("1", translatef("%d second", 1)) + timeout:value("2", translatef("%d seconds", 2)) + timeout:value("3", translatef("%d seconds", 3)) + timeout:value("4", translatef("%d seconds", 4)) + timeout:value("5", translatef("%d seconds", 5)) + timeout:value("6", translatef("%d seconds", 6)) + timeout:value("7", translatef("%d seconds", 7)) + timeout:value("8", translatef("%d seconds", 8)) + timeout:value("9", translatef("%d seconds", 9)) + timeout:value("10", translatef("%d seconds", 10)) + +interval = mwan_interface:option(ListValue, "interval", translate("Ping interval")) + interval.default = "5" + interval:value("1", translatef("%d second", 1)) + interval:value("3", translatef("%d seconds", 3)) + interval:value("5", translatef("%d seconds", 5)) + interval:value("10", translatef("%d seconds", 10)) + interval:value("20", translatef("%d seconds", 20)) + interval:value("30", translatef("%d seconds", 30)) + interval:value("60", translatef("%d minute", 1)) + interval:value("300", translatef("%d minutes", 5)) + interval:value("600", translatef("%d minutes", 10)) + interval:value("900", translatef("%d minutes", 15)) + interval:value("1800", translatef("%d minutes", 30)) + interval:value("3600", translatef("%d hour", 1)) + +failure = mwan_interface:option(Value, "failure_interval", translate("Failure interval"), + translate("Ping interval during failure detection")) + failure.default = "5" + failure:value("1", translatef("%d second", 1)) + failure:value("3", translatef("%d seconds", 3)) + failure:value("5", translatef("%d seconds", 5)) + failure:value("10", translatef("%d seconds", 10)) + failure:value("20", translatef("%d seconds", 20)) + failure:value("30", translatef("%d seconds", 30)) + failure:value("60", translatef("%d minute", 1)) + failure:value("300", translatef("%d minutes", 5)) + failure:value("600", translatef("%d minutes", 10)) + failure:value("900", translatef("%d minutes", 15)) + failure:value("1800", translatef("%d minutes", 30)) + failure:value("3600", translatef("%d hour", 1)) + +recovery = mwan_interface:option(Value, "recovery_interval", translate("Recovery interval"), + translate("Ping interval during failure recovering")) + recovery.default = "5" + recovery:value("1", translatef("%d second", 1)) + recovery:value("3", translatef("%d seconds", 3)) + recovery:value("5", translatef("%d seconds", 5)) + recovery:value("10", translatef("%d seconds", 10)) + recovery:value("20", translatef("%d seconds", 20)) + recovery:value("30", translatef("%d seconds", 30)) + recovery:value("60", translatef("%d minute", 1)) + recovery:value("300", translatef("%d minutes", 5)) + recovery:value("600", translatef("%d minutes", 10)) + recovery:value("900", translatef("%d minutes", 15)) + recovery:value("1800", translatef("%d minutes", 30)) + recovery:value("3600", translatef("%d hour", 1)) + +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") + +flush = mwan_interface:option(ListValue, "flush_conntrack", translate("Flush conntrack table"), + translate("Flush global firewall conntrack table on interface events")) + flush.default = "never" + flush:value("ifup", translate("ifup")) + flush:value("ifdown", translate("ifdown")) + flush:value("never", translate("never")) + flush:value("always", translate("always")) + +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/po/ja/mwan3.po b/applications/luci-app-mwan3/po/ja/mwan3.po new file mode 100644 index 0000000000..2df8fead33 --- /dev/null +++ b/applications/luci-app-mwan3/po/ja/mwan3.po @@ -0,0 +1,519 @@ +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 2.0\n" +"Last-Translator: INAGAKI Hiroshi <musashino.open@gmail.com>\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"Language: ja\n" + +msgid "%d hour" +msgstr "%d 時間" + +msgid "%d minute" +msgstr "%d 分" + +msgid "%d minutes" +msgstr "%d 分" + +msgid "%d second" +msgstr "%d 秒" + +msgid "%d seconds" +msgstr "%d 秒" + +msgid "" +"Acceptable values: 1-100. This many Tracking IP addresses must respond for " +"the link to be deemed up" +msgstr "" +"利用可能な値: 1-100。上記の追跡 IP の合計個数のうち、Up 状態と判定するために" +"に必要な、レスポンスが返された追跡 IP アドレスの個数です。" + +msgid "Acceptable values: 1-1000. Defaults to 1 if not set" +msgstr "利用可能な値: 1-1000。空欄の場合のデフォルトは1です。" + +msgid "Advanced" +msgstr "詳細設定" + +msgid "Check IP rules" +msgstr "IP ルールのチェック" + +msgid "Check routing table" +msgstr "ルーティング テーブルのチェック" + +msgid "Configuration" +msgstr "設定" + +msgid "Currently Configured Interfaces" +msgstr "設定済みインターフェース" + +msgid "Currently Configured Members" +msgstr "設定済みメンバー" + +msgid "Currently Configured Policies" +msgstr "設定済みポリシー" + +msgid "Destination address" +msgstr "宛先アドレス" + +msgid "Destination port" +msgstr "宛先ポート" + +msgid "Detailed Status" +msgstr "詳細ステータス" + +msgid "Diagnostic Results" +msgstr "診断結果" + +msgid "Diagnostics" +msgstr "診断機能" + +msgid "" +"Downed interface will be deemed up after this many successful ping tests" +msgstr "" +"Down 状態のインターフェースが Up 状態と判断されるまでに要する ping テストの成" +"功回数です。" + +msgid "Enabled" +msgstr "有効" + +msgid "Errors" +msgstr "エラー" + +msgid "Failure interval" +msgstr "障害検出 インターバル" + +msgid "Flush conntrack table" +msgstr "" + +msgid "Flush global firewall conntrack table on interface events" +msgstr "" + +msgid "Hotplug Script" +msgstr "ホットプラグ スクリプト" + +msgid "Hotplug ifdown" +msgstr "ホットプラグ ifdown" + +msgid "Hotplug ifup" +msgstr "ホットプラグ ifup" + +msgid "IPset" +msgstr "IPset" + +msgid "IPv4" +msgstr "IPv4" + +msgid "IPv6" +msgstr "IPv6" + +msgid "Interface" +msgstr "インターフェース" + +msgid "Interface Status" +msgstr "インターフェース ステータス" + +msgid "Interface down" +msgstr "インターフェース Down" + +msgid "Interface up" +msgstr "インターフェース Up" + +msgid "Interface will be deemed down after this many failed ping tests" +msgstr "" +"インターフェースが Down 状態と判断されるまでに要する ping テストの失敗回数で" +"す。" + +msgid "Interfaces" +msgstr "インターフェース" + +msgid "Internet Protocol" +msgstr "インターネット プロトコル" + +msgid "Last resort" +msgstr "最終手段" + +msgid "Load Balancing" +msgstr "負荷分散" + +msgid "Loading" +msgstr "読込中" + +msgid "MWAN Config" +msgstr "MWAN 設定" + +msgid "MWAN Detailed Status" +msgstr "MWAN 詳細ステータス" + +msgid "MWAN Interface Configuration" +msgstr "MWAN インターフェース設定" + +msgid "MWAN Interface Configuration -" +msgstr "MWAN インターフェース設定 -" + +msgid "MWAN Interface Diagnostics" +msgstr "MWAN インターフェース診断" + +msgid "MWAN Interface Live Status" +msgstr "MWAN インターフェース Live ステータス" + +msgid "MWAN Interface Systemlog" +msgstr "MWAN インターフェース システムログ" + +msgid "MWAN Member Configuration" +msgstr "MWAN メンバー設定" + +msgid "MWAN Member Configuration -" +msgstr "MWAN メンバー設定 -" + +msgid "MWAN Policy Configuration" +msgstr "MWAN ポリシー設定" + +msgid "MWAN Policy Configuration -" +msgstr "MWAN ポリシー設定 -" + +msgid "MWAN Rule Configuration" +msgstr "MWAN ルール設定" + +msgid "MWAN Rule Configuration -" +msgstr "MWAN ルール設定 -" + +msgid "MWAN Service Control" +msgstr "MWAN サービス コントロール" + +msgid "" +"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" +msgstr "" +"MWAN は、250個までの物理または論理、あるいは両方のインターフェースをサポート" +"します。<br />MWAN は、全てのインターフェースが /etc/config/network で設定さ" +"れるユニークなメトリックを持つことを必要とします。<br />下記 \"インターフェー" +"ス\" の名前は、 /etc/config/network に存在するインターフェース名と同じでなけ" +"ればなりません(詳細設定タブを確認)。<br />名前は A-Z, a-z, 0-9, _ を含むこ" +"とができますが、スペースは使用できません。<br />インターフェースには、設定済" +"みのメンバーやポリシー、ルールと同じ名前を使用することはできません。" + +msgid "" +"May be entered as a single or multiple port(s) (eg \"22\" or \"80,443\") or " +"as a portrange (eg \"1024:2048\") without quotes" +msgstr "" +"単一または複数のポート(例: \"22\" または \"80,443\")、あるいはポートの範囲" +"(例: \"1024:2048\")を、クオーテーション無しで指定することができます。" + +msgid "Member used" +msgstr "使用されるメンバー" + +msgid "Members" +msgstr "メンバー" + +msgid "" +"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" +msgstr "" +"メンバーは、MWAN インターフェースのメトリックおよびウエイトを関連付けたプロ" +"ファイルです。<br />名前は A-Z, a-z, 0-9, _ を含むことができますが、スペース" +"は使用できません。<br />メンバーには、設定済みのインターフェースやポリシー、" +"ルールと同じ名前を使用することはできません。" + +msgid "Members assigned" +msgstr "アサイン済みメンバー" + +msgid "Metric" +msgstr "メトリック" + +msgid "" +"Name of IPset rule. Requires IPset rule in /etc/dnsmasq.conf (eg \"ipset=/" +"youtube.com/youtube\")" +msgstr "" +"IPset ルールの名前です。このルールは、 /etc/dnsmasq.conf で必要です。(例: " +"\"ipset=/youtube.com/youtube\")" + +msgid "Network Config" +msgstr "ネットワーク設定" + +msgid "No" +msgstr "いいえ" + +msgid "Overview" +msgstr "概要" + +msgid "Ping count" +msgstr "Ping 回数" + +msgid "Ping default gateway" +msgstr "Ping デフォルト ゲートウェイ" + +msgid "Ping interval" +msgstr "Ping インターバル" + +msgid "Ping interval during failure detection" +msgstr "障害検出動作中の Ping 実行間隔です。" + +msgid "Ping interval during failure recovering" +msgstr "障害復旧中の Ping 実行間隔です。" + +msgid "Ping size" +msgstr "Ping サイズ" + +msgid "Ping timeout" +msgstr "Ping タイムアウト" + +msgid "Ping tracking IP" +msgstr "Ping トラッキング IP" + +msgid "Policies" +msgstr "ポリシー" + +msgid "" +"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" +msgstr "" +"ポリシーは、MWANがどのようにトラフィックの分配を行うかを制御する、1つ以上のメ" +"ンバーをグループ化するプロファイルです。<br />最小のメトリックを持つメンバー " +"インターフェースが最初に使用されます。同じメトリックを持つ複数のインター" +"フェースでは、負荷分散を行います。<br />負荷分散に設定されたメンバー インター" +"フェースでは、ウェイトの値が大きい方により多くのトラフィックを分配します。" +"<br />名前は A-Z, a-z, 0-9, _ を含むことができますが、スペースは使用できませ" +"ん。また、15文字以内でなければなりません。<br />ポリシーでは、設定済みのイン" +"ターフェースやメンバー、ルールと同じ名前を使用することはできません。" + +msgid "Policy assigned" +msgstr "アサイン済みポリシー" + +msgid "Protocol" +msgstr "プロトコル" + +msgid "Recovery interval" +msgstr "障害復旧 インターバル" + +msgid "Restart MWAN" +msgstr "MWAN の再起動" + +msgid "Restore default hotplug script" +msgstr "デフォルトのホットプラグ スクリプトの復元" + +msgid "Restore..." +msgstr "復元..." + +msgid "Rules" +msgstr "ルール" + +msgid "" +"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" +msgstr "" +"ルールは IP アドレスやポート、プロトコルを基に、トラフィックがどの MWAN ポリ" +"シーを使用するかを設定します。<br />ルールは上から下へマッチングが行われ、合" +"致したルールより下のルールは無視されます。全てのルールに合致しないトラフィッ" +"クは、メインのルーティング テーブルを使用してルートが決定されます。<br />既知" +"(デフォルト以外)のネットワークへのトラフィックは、メインのルーティング テー" +"ブルによって制御されます。ルールに合致したトラフィックでも、当該ポリシーの全 " +"WAN インターフェースが Down 状態の場合は blackhole 状態となります。<br />名前" +"は A-Z, a-z, 0-9, _ を含むことができますが、スペースは使用できません。<br />" +"ルールは、設定済みのインターフェースやメンバー、ポリシーと同じ名前を使用する" +"ことはできません。" + +msgid "Seconds. Acceptable values: 1-1000000. Defaults to 600 if not set" +msgstr "秒。利用可能な値: 1-1000000。空欄の場合のデフォルト値は600です。" + +msgid "Source address" +msgstr "送信元アドレス" + +msgid "Source port" +msgstr "送信元ポート" + +msgid "Start MWAN" +msgstr "MWAN の起動" + +msgid "Sticky" +msgstr "Sticky" + +msgid "Sticky timeout" +msgstr "Sticky タイムアウト" + +msgid "Stop MWAN" +msgstr "MWAN の停止" + +msgid "Supports CIDR notation (eg \"192.168.100.0/24\") without quotes" +msgstr "CIDR 表記のサポート(例: \"192.168.100.0/24\")" + +msgid "" +"This IP address will be pinged to dermine if the link is up or down. Leave " +"blank to assume interface is always online" +msgstr "" +"これらは、リンクの Up または Down を判定するために Ping が送信されるIP アドレ" +"スです。常にオンラインとする場合、空欄のままにします。" + +msgid "" +"This displays the metric assigned to this interface in /etc/config/network" +msgstr "" +"/etc/config/network で、このインターフェースに割り当てられたメトリックです。" + +msgid "This section allows you to modify the contents of /etc/config/mwan3" +msgstr "" +"このセクションでは、 /etc/config/mwan3 の内容を変更することができます。" + +msgid "This section allows you to modify the contents of /etc/config/network" +msgstr "" +"このセクションでは、 /etc/config/network の内容を変更することができます。" + +msgid "This section allows you to modify the contents of /etc/config/wireless" +msgstr "" +"このセクションでは、 /etc/config/wireless の内容を変更することができます。" + +msgid "" +"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.)" +msgstr "" +"このセクションでは、 /etc/hotplug.d/iface/16-mwancustom の内容を変更すること" +"ができます。<br />これは、インターフェースの ifup または ifdown ホットプラグ " +"イベント時にシステムコマンドまたはスクリプト、もしくはその両方を実行すること" +"に役立ちます。<br /><br />注意:<br />スクリプトの1行目は、"#!bin/sh" " +"である必要があります(クオーテーション不要)。<br /># で始まる行はコメントと" +"して認識され、実行されません。<br /><br />利用可能な変数:<br />$ACTION - ホッ" +"トプラグ イベント (ifup, ifdown)<br />$INTERFACE - インターフェース名(wan1, " +"wan2, その他)<br />$DEVICE - インターフェースにアタッチされたデバイスの名前" +"(eth0.1, eth1, その他)" + +msgid "Tracking IP" +msgstr "追跡 IP" + +msgid "Tracking reliability" +msgstr "追跡の信頼性" + +msgid "Traffic Rules" +msgstr "トラフィック ルール" + +msgid "" +"Traffic from the same source IP address that previously matched this rule " +"within the sticky timeout period will use the same WAN interface" +msgstr "" +"以前このルールにマッチした同じアクセス元 IP アドレスからのトラフィックが、再" +"度 Sticky 制限時間内にマッチした場合には、同じ WAN インターフェースが使用され" +"ます。" + +msgid "Troubleshooting" +msgstr "トラブルシューティング" + +msgid "Troubleshooting Data" +msgstr "トラブルシューティング データ" + +msgid "View the contents of /etc/protocols for protocol descriptions" +msgstr "プロトコルの説明については、 /etc/protocols の内容を確認してください。" + +msgid "Weight" +msgstr "ウエイト" + +msgid "" +"When all policy members are offline use this behavior for matched traffic" +msgstr "" +"ポリシーの全メンバーがオフラインの場合、合致したトラフィックに対してこのふる" +"まいが使用されます。" + +msgid "Wireless Config" +msgstr "無線設定" + +msgid "Yes" +msgstr "はい" + +msgid "always" +msgstr "always" + +msgid "blackhole (drop)" +msgstr "blackhole (drop)" + +msgid "default (use main routing table)" +msgstr "デフォルト(メインのルーティング テーブルを使用)" + +msgid "ifdown" +msgstr "ifdown" + +msgid "ifup" +msgstr "ifup" + +msgid "never" +msgstr "never" + +msgid "unreachable (reject)" +msgstr "unreachable (reject)" + +#~ msgid "1 hour" +#~ msgstr "1時間" + +#~ msgid "1 minute" +#~ msgstr "1分" + +#~ msgid "1 second" +#~ msgstr "1秒" + +#~ msgid "10 minutes" +#~ msgstr "10分" + +#~ msgid "10 seconds" +#~ msgstr "10秒" + +#~ msgid "15 minutes" +#~ msgstr "15分" + +#~ msgid "2 seconds" +#~ msgstr "2秒" + +#~ msgid "20 seconds" +#~ msgstr "20秒" + +#~ msgid "3 seconds" +#~ msgstr "3秒" + +#~ msgid "30 minutes" +#~ msgstr "30分" + +#~ msgid "30 seconds" +#~ msgstr "30秒" + +#~ msgid "4 seconds" +#~ msgstr "4秒" + +#~ msgid "5 minutes" +#~ msgstr "5分" + +#~ msgid "5 seconds" +#~ msgstr "5秒" + +#~ msgid "6 seconds" +#~ msgstr "6秒" + +#~ msgid "7 seconds" +#~ msgstr "7秒" + +#~ msgid "8 seconds" +#~ msgstr "8秒" + +#~ msgid "9 seconds" +#~ msgstr "9秒" diff --git a/applications/luci-app-mwan3/po/templates/mwan3.pot b/applications/luci-app-mwan3/po/templates/mwan3.pot new file mode 100644 index 0000000000..0b423c85a5 --- /dev/null +++ b/applications/luci-app-mwan3/po/templates/mwan3.pot @@ -0,0 +1,395 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +msgid "%d hour" +msgstr "" + +msgid "%d minute" +msgstr "" + +msgid "%d minutes" +msgstr "" + +msgid "%d second" +msgstr "" + +msgid "%d seconds" +msgstr "" + +msgid "" +"Acceptable values: 1-100. This many Tracking IP addresses must respond for " +"the link to be deemed up" +msgstr "" + +msgid "Acceptable values: 1-1000. Defaults to 1 if not set" +msgstr "" + +msgid "Advanced" +msgstr "" + +msgid "Check IP rules" +msgstr "" + +msgid "Check routing table" +msgstr "" + +msgid "Configuration" +msgstr "" + +msgid "Currently Configured Interfaces" +msgstr "" + +msgid "Currently Configured Members" +msgstr "" + +msgid "Currently Configured Policies" +msgstr "" + +msgid "Destination address" +msgstr "" + +msgid "Destination port" +msgstr "" + +msgid "Detailed Status" +msgstr "" + +msgid "Diagnostic Results" +msgstr "" + +msgid "Diagnostics" +msgstr "" + +msgid "" +"Downed interface will be deemed up after this many successful ping tests" +msgstr "" + +msgid "Enabled" +msgstr "" + +msgid "Errors" +msgstr "" + +msgid "Failure interval" +msgstr "" + +msgid "Flush conntrack table" +msgstr "" + +msgid "Flush global firewall conntrack table on interface events" +msgstr "" + +msgid "Hotplug Script" +msgstr "" + +msgid "Hotplug ifdown" +msgstr "" + +msgid "Hotplug ifup" +msgstr "" + +msgid "IPset" +msgstr "" + +msgid "IPv4" +msgstr "" + +msgid "IPv6" +msgstr "" + +msgid "Interface" +msgstr "" + +msgid "Interface Status" +msgstr "" + +msgid "Interface down" +msgstr "" + +msgid "Interface up" +msgstr "" + +msgid "Interface will be deemed down after this many failed ping tests" +msgstr "" + +msgid "Interfaces" +msgstr "" + +msgid "Internet Protocol" +msgstr "" + +msgid "Last resort" +msgstr "" + +msgid "Load Balancing" +msgstr "" + +msgid "Loading" +msgstr "" + +msgid "MWAN Config" +msgstr "" + +msgid "MWAN Detailed Status" +msgstr "" + +msgid "MWAN Interface Configuration" +msgstr "" + +msgid "MWAN Interface Configuration -" +msgstr "" + +msgid "MWAN Interface Diagnostics" +msgstr "" + +msgid "MWAN Interface Live Status" +msgstr "" + +msgid "MWAN Interface Systemlog" +msgstr "" + +msgid "MWAN Member Configuration" +msgstr "" + +msgid "MWAN Member Configuration -" +msgstr "" + +msgid "MWAN Policy Configuration" +msgstr "" + +msgid "MWAN Policy Configuration -" +msgstr "" + +msgid "MWAN Rule Configuration" +msgstr "" + +msgid "MWAN Rule Configuration -" +msgstr "" + +msgid "MWAN Service Control" +msgstr "" + +msgid "" +"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" +msgstr "" + +msgid "" +"May be entered as a single or multiple port(s) (eg \"22\" or \"80,443\") or " +"as a portrange (eg \"1024:2048\") without quotes" +msgstr "" + +msgid "Member used" +msgstr "" + +msgid "Members" +msgstr "" + +msgid "" +"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" +msgstr "" + +msgid "Members assigned" +msgstr "" + +msgid "Metric" +msgstr "" + +msgid "" +"Name of IPset rule. Requires IPset rule in /etc/dnsmasq.conf (eg \"ipset=/" +"youtube.com/youtube\")" +msgstr "" + +msgid "Network Config" +msgstr "" + +msgid "No" +msgstr "" + +msgid "Overview" +msgstr "" + +msgid "Ping count" +msgstr "" + +msgid "Ping default gateway" +msgstr "" + +msgid "Ping interval" +msgstr "" + +msgid "Ping interval during failure detection" +msgstr "" + +msgid "Ping interval during failure recovering" +msgstr "" + +msgid "Ping size" +msgstr "" + +msgid "Ping timeout" +msgstr "" + +msgid "Ping tracking IP" +msgstr "" + +msgid "Policies" +msgstr "" + +msgid "" +"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" +msgstr "" + +msgid "Policy assigned" +msgstr "" + +msgid "Protocol" +msgstr "" + +msgid "Recovery interval" +msgstr "" + +msgid "Restart MWAN" +msgstr "" + +msgid "Restore default hotplug script" +msgstr "" + +msgid "Restore..." +msgstr "" + +msgid "Rules" +msgstr "" + +msgid "" +"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" +msgstr "" + +msgid "Seconds. Acceptable values: 1-1000000. Defaults to 600 if not set" +msgstr "" + +msgid "Source address" +msgstr "" + +msgid "Source port" +msgstr "" + +msgid "Start MWAN" +msgstr "" + +msgid "Sticky" +msgstr "" + +msgid "Sticky timeout" +msgstr "" + +msgid "Stop MWAN" +msgstr "" + +msgid "Supports CIDR notation (eg \"192.168.100.0/24\") without quotes" +msgstr "" + +msgid "" +"This IP address will be pinged to dermine if the link is up or down. Leave " +"blank to assume interface is always online" +msgstr "" + +msgid "" +"This displays the metric assigned to this interface in /etc/config/network" +msgstr "" + +msgid "This section allows you to modify the contents of /etc/config/mwan3" +msgstr "" + +msgid "This section allows you to modify the contents of /etc/config/network" +msgstr "" + +msgid "This section allows you to modify the contents of /etc/config/wireless" +msgstr "" + +msgid "" +"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.)" +msgstr "" + +msgid "Tracking IP" +msgstr "" + +msgid "Tracking reliability" +msgstr "" + +msgid "Traffic Rules" +msgstr "" + +msgid "" +"Traffic from the same source IP address that previously matched this rule " +"within the sticky timeout period will use the same WAN interface" +msgstr "" + +msgid "Troubleshooting" +msgstr "" + +msgid "Troubleshooting Data" +msgstr "" + +msgid "View the contents of /etc/protocols for protocol descriptions" +msgstr "" + +msgid "Weight" +msgstr "" + +msgid "" +"When all policy members are offline use this behavior for matched traffic" +msgstr "" + +msgid "Wireless Config" +msgstr "" + +msgid "Yes" +msgstr "" + +msgid "always" +msgstr "" + +msgid "blackhole (drop)" +msgstr "" + +msgid "default (use main routing table)" +msgstr "" + +msgid "ifdown" +msgstr "" + +msgid "ifup" +msgstr "" + +msgid "never" +msgstr "" + +msgid "unreachable (reject)" +msgstr "" 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-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..7926595b6e --- /dev/null +++ b/applications/luci-app-simple-adblock/po/ja/simple-adblock.po @@ -0,0 +1,93 @@ +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/po/pt-br/vpnbypass.po b/applications/luci-app-vpnbypass/po/pt-br/vpnbypass.po index 5adc5ed4f4..9f3fa2a679 100644 --- a/applications/luci-app-vpnbypass/po/pt-br/vpnbypass.po +++ b/applications/luci-app-vpnbypass/po/pt-br/vpnbypass.po @@ -18,8 +18,8 @@ msgstr "Domínios para evitar a VPN" msgid "Domains to be accessed directly (outside of the VPN tunnel), see" msgstr "" -msgid "Enable VPN Bypass" -msgstr "Habilitar o VPN Bypass" +msgid "Enable/start service" +msgstr "" msgid "Local IP Addresses to Bypass" msgstr "" @@ -61,6 +61,9 @@ msgstr "Configurações do VPN Bypass" msgid "for syntax" msgstr "" +#~ msgid "Enable VPN Bypass" +#~ msgstr "Habilitar o VPN Bypass" + #~ msgid "Configuration of VPN Bypass Settings" #~ msgstr "Configurações do VPN Bypass" |