openwrt-18.06: merge master

Due to a huge number of fixes and diverging development histories, I decided
to completely merge the current LuCI master into the 18.06 release branch to
have a common code base for upcoming maintenance releases.

Some LuCI apps have minor style glitches yet but I do not deem them to be
release critical as non-default components need to be opkg-installed anyway
and the package repositories are continuously refreshed, so we do not need
to fix everything for OpenWrt 18.06.0-rc2.

The most important changes introduced by this merge are:

1) New HTTP handling library in C

  The new library should vastly reduce the required RAM for processing
  large POST bodies while implementing some slightly more strict parsing
  logic.

2) Apply/Rollback workflow

  The ubus rpcd based apply/rollback handling will automatically revert
  config changes if access to the device is lost for a certain period
  of time, this is mainly intended for preventing issues with bad
  config settings and the like.

  The feature is not 100% error-proof yet but it successfully prevents a
  large number of issues already. For final, the handling of the firewall
  conntrack cache needs to be fixed yet as adding "lockout" firewall rules
  is not yet catched due to the open HTTP session allowed by netfilter
  conntrack

3) Template markup and theme style modifications

  A large number of changes have been made to the markup in the various
  templates, mainly to allow for responsive styling of tables.

  The only theme currently making full use of that is the non-default
  OpenWrt theme which will break table rows into disjunct boxes on
  very narrow screens.

  The changes have been tested on IE 11, MS Edge, Firefox, Chrome, an
  iPhone 5s, iPhone 6 and iPad Air.

4) Initial LuCI support for displaying virtual dynamic network interfaces

  Some protocol handlers will spawn purely dynamic sub-interfaces which
  are not present in UCI. Such interfaces have been invisible in LuCI so
  far which caused confusion especialy wrt. missing IP addresses etc.

  LuCI will now display such dynamic interfaces on the interface overview.

5) Initial LuCI support for display interface runtime error information

  LuCI will now expose interface error information stored in the ubus
  runtime information by protocol handlers.

  This is mainly useful to get notified of low level problems like
  bad SIM codes are missing APN information.

6) Various XSS and CSRF bypass fixes

  A number of code places performing inadequate markup escaping have been
  fixed and the dispatcher CSRF token enforcement rules have been reworked
  to actually catch all POST security cases.

7) Initial support for running under nginx

  Various bugs have been fixed to allow LuCI to function under nginx using
  a FastCGI wrapper.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
Jo-Philipp Wich 2018-07-13 17:02:22 +02:00
commit fb817df836
249 changed files with 17761 additions and 9390 deletions

View file

@ -1,22 +1,21 @@
-- Copyright 2017 Dirk Brenken (dev@brenken.org)
-- Copyright 2017-2018 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("luci.model.uci").cursor()
local fs = require("nixio.fs")
local util = require("luci.util")
local uci = require("luci.model.uci").cursor()
local adbinput = uci:get("adblock", "blacklist", "adb_src") or "/etc/adblock/adblock.blacklist"
if not nixio.fs.access(adbinput) then
m = SimpleForm("error", nil,
translate("Input file not found, please check your configuration."))
if not fs.access(adbinput) then
m = SimpleForm("error", nil, translate("Input file not found, please check your configuration."))
m.reset = false
m.submit = false
return m
end
if nixio.fs.stat(adbinput).size > 524288 then
if fs.stat(adbinput).size >= 102400 then
m = SimpleForm("error", nil,
translate("The file size is too large for online editing in LuCI (&gt; 512 KB). ")
translate("The file size is too large for online editing in LuCI (&ge; 100 KB). ")
.. translate("Please edit this file directly in a terminal session."))
m.reset = false
m.submit = false
@ -38,11 +37,11 @@ f.rows = 20
f.rmempty = true
function f.cfgvalue()
return nixio.fs.readfile(adbinput) or ""
return 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")
return fs.writefile(adbinput, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n")
end
function s.handle(self, state, data)

View file

@ -1,17 +1,26 @@
-- Copyright 2017 Dirk Brenken (dev@brenken.org)
-- Copyright 2017-2018 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 fs = require("nixio.fs")
local util = require("luci.util")
local adbinput = "/etc/config/adblock"
if not nixio.fs.access(adbinput) then
if not fs.access(adbinput) then
m = SimpleForm("error", nil, translate("Input file not found, please check your configuration."))
m.reset = false
m.submit = false
return m
end
if fs.stat(adbinput).size >= 102400 then
m = SimpleForm("error", nil,
translate("The file size is too large for online editing in LuCI (&ge; 100 KB). ")
.. translate("Please edit this file directly in a terminal session."))
m.reset = false
m.submit = false
return m
end
m = SimpleForm("input", nil)
m:append(Template("adblock/config_css"))
m.submit = translate("Save")
@ -25,11 +34,11 @@ f.rows = 20
f.rmempty = true
function f.cfgvalue()
return nixio.fs.readfile(adbinput) or ""
return 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")
return fs.writefile(adbinput, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n")
end
function s.handle(self, state, data)

View file

@ -183,7 +183,7 @@ end
des = bl:option(DummyValue, "adb_src_desc", translate("Description"))
cat = bl:option(DynamicList, "adb_src_cat", translate("Categories"))
cat = bl:option(DynamicList, "adb_src_cat", translate("Archive Categories"))
cat.datatype = "uciname"
cat.optional = true

View file

@ -1,22 +1,22 @@
-- Copyright 2017 Dirk Brenken (dev@brenken.org)
-- Copyright 2017-2018 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("luci.model.uci").cursor()
local fs = require("nixio.fs")
local util = require("luci.util")
local uci = require("luci.model.uci").cursor()
local adbinput = uci:get("adblock", "global", "adb_whitelist") or "/etc/adblock/adblock.whitelist"
if not nixio.fs.access(adbinput) then
if not fs.access(adbinput) then
m = SimpleForm("error", nil, translate("Input file not found, please check your configuration."))
m.reset = false
m.submit = false
return m
end
if nixio.fs.stat(adbinput).size > 524288 then
if fs.stat(adbinput).size >= 102400 then
m = SimpleForm("error", nil,
translate("The file size is too large for online editing in LuCI (&gt; 512 KB). ")
.. translate("Please edit this file directly in a terminal session."))
translate("The file size is too large for online editing in LuCI (&ge; 100 KB). ")
.. translate("Please edit this file directly in a terminal session."))
m.reset = false
m.submit = false
return m
@ -37,11 +37,11 @@ f.rows = 20
f.rmempty = true
function f.cfgvalue()
return nixio.fs.readfile(adbinput) or ""
return 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")
return fs.writefile(adbinput, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n")
end
function s.handle(self, state, data)

View file

@ -22,66 +22,77 @@ end
-%>
<style type="text/css">
table.cbi-section-table th,
table.cbi-section-table td,
.table.cbi-section-table .th,
.table.cbi-section-table .td,
.cbi-section-table-cell,
.cbi-section-table-row,
.cbi-input-text
.cbi-section-table-row
{
text-align:left;
vertical-align:top;
margin-right:auto;
margin-left:0px;
padding-left:2px;
line-height:20px;
}
.table.cbi-section-table .th
{
white-space:nowrap;
}
.table.cbi-section-table input
{
width:7em;
}
.cbi-input-text
{
text-align:left;
padding-left:2px;
outline:none;
box-shadow:none;
background:transparent;
padding-left:2px;
line-height:25px;
height:25px;
height:20px;
width:10em;
}
</style>
<%-
local anonclass = (not self.anonymous or self.sectiontitle) and "named" or "anonymous"
local titlename = ifattr(not self.anonymous or self.sectiontitle, "data-title", translate("Name"))
-%>
<fieldset class="cbi-section" id="cbi-<%=self.config%>-<%=self.sectiontype%>">
<% if self.title then -%>
<legend><%=self.title%></legend>
<%- end %>
<div class="cbi-section-descr"><%=self.description%></div>
<div class="cbi-section-node">
<table class="cbi-section-table">
<tr class="cbi-section-table-titles">
<%- if self.sectionhead then -%>
<th class="cbi-section-table-cell"><%=self.sectionhead%></th>
<%- else -%>
<th>&#160;</th>
<%- end -%>
<div class="table cbi-section-table">
<div class="tr cbi-section-table-titles <%=anonclass%>"<%=titlename%>>
<%- for i, k in pairs(self.children) do -%>
<th class="cbi-section-table-cell"<%=width(k)%>>
<div class="th cbi-section-table-cell"<%=width(k)%>>
<%-=k.title-%>
</th>
</div>
<%- end -%>
</tr>
</div>
<%- local isempty = true
for i, k in ipairs(self:cfgsections()) do
section = k
local section = k
local sectionname = striptags((type(self.sectiontitle) == "function") and self:sectiontitle(section) or k)
local sectiontitle = ifattr(sectionname and (not self.anonymous or self.sectiontitle), "data-title", sectionname)
isempty = false
scope = { valueheader = "cbi/cell_valueheader", valuefooter = "cbi/cell_valuefooter" }
-%>
<tr class="cbi-section-table-row" id="cbi-<%=self.config%>-<%=section%>">
<th><%=k%></th>
<div class="tr cbi-section-table-row" id="cbi-<%=self.config%>-<%=section%>"<%=sectiontitle%>>
<%-
for k, node in ipairs(self.children) do
node:render(section, scope or {})
end
if not scope.cbid:match("adb_src_cat") then
-%>
<td class="cbi-value-field">&#160;</td>
<div class="td cbi-value-field">&#160;</div>
<%- end -%>
</tr>
</div>
<%- end -%>
</table>
</div>
</div>
</fieldset>

View file

@ -5,7 +5,6 @@ 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();
@ -35,7 +34,7 @@ This is free software, licensed under the Apache License, Version 2.0
else
{
input.style.display = 'none';
output.innerHTML = '<span class="error"><%:Invalid domain specified!%></span>';
output.innerHTML = '<span class="error"><%:Blocklist not found!%></span>';
}
}
);

View file

@ -49,9 +49,7 @@ msgstr ""
msgid "Blocklist Sources"
msgstr "Fonti lista di Blocco"
msgid ""
"Builds an additional 'Jail' list (/tmp/adb_list.jail) to block access to all "
"domains except those listed in the whitelist file.<br />"
msgid "Blocklist not found!"
msgstr ""
msgid "Categories"
@ -169,9 +167,6 @@ msgstr ""
msgid "Input file not found, please check your configuration."
msgstr "File di input non trovato, per favore controlla la tua configurazione."
msgid "Invalid domain specified!"
msgstr "Dominio invalido specificato!"
msgid "Last Run"
msgstr "Ultimo Avvio"
@ -280,10 +275,8 @@ msgstr ""
msgid "Target directory for the generated blocklist 'adb_list.overall'."
msgstr "Directory per la lista di blocco generata 'adb_list.overall'."
msgid "The file size is too large for online editing in LuCI (&gt; 512 KB)."
msgid "The file size is too large for online editing in LuCI (&ge; 100 KB)."
msgstr ""
"La grandezza del file è troppo grande per modificarla online in LuCI (&gt; "
"512 KB)."
msgid ""
"This form allows you to modify the content of the adblock blacklist (%s)."

View file

@ -51,6 +51,9 @@ msgstr "バックアップ モード"
msgid "Blocklist Sources"
msgstr "ブロックリスト提供元"
msgid "Blocklist not found!"
msgstr ""
msgid ""
"Builds an additional 'Jail' list (/tmp/adb_list.jail) to block access to all "
"domains except those listed in the whitelist file.<br />"
@ -185,9 +188,6 @@ msgstr "ホワイトリスト ファイルへのフルパスです。"
msgid "Input file not found, please check your configuration."
msgstr "入力ファイルが見つかりません。設定を確認してください。"
msgid "Invalid domain specified!"
msgstr "無効なドメインが指定されています!"
msgid "Last Run"
msgstr "最終実行"
@ -304,10 +304,10 @@ msgstr ""
msgid "Target directory for the generated blocklist 'adb_list.overall'."
msgstr "生成されたブロックリスト 'adb_list.overall' の保存先ディレクトリです。"
msgid "The file size is too large for online editing in LuCI (&gt; 512 KB)."
msgid "The file size is too large for online editing in LuCI (&ge; 100 KB)."
msgstr ""
"ファイル サイズが大きすぎる512 KB超ため、 LuCI 上でオンライン編集できませ"
"。"
"LuCI上でのオンライン編集を行うには、ファイルサイズが大きすぎます (&ge; 100 "
"KB)。"
msgid ""
"This form allows you to modify the content of the adblock blacklist (%s)."

View file

@ -52,9 +52,7 @@ msgstr ""
msgid "Blocklist Sources"
msgstr "Fontes de listas de bloqueio"
msgid ""
"Builds an additional 'Jail' list (/tmp/adb_list.jail) to block access to all "
"domains except those listed in the whitelist file.<br />"
msgid "Blocklist not found!"
msgstr ""
msgid "Categories"
@ -169,9 +167,6 @@ msgstr ""
msgid "Input file not found, please check your configuration."
msgstr "Arquivo de entrada não encontrado, por favor cheque sua configuração."
msgid "Invalid domain specified!"
msgstr "Domínio especificado inválido!"
msgid "Last Run"
msgstr ""
@ -274,9 +269,8 @@ msgstr ""
msgid "Target directory for the generated blocklist 'adb_list.overall'."
msgstr ""
msgid "The file size is too large for online editing in LuCI (&gt; 512 KB)."
msgid "The file size is too large for online editing in LuCI (&ge; 100 KB)."
msgstr ""
"O tamanho do arquivo é muito grande para edição online no LuCI (&gt; 512 KB)."
msgid ""
"This form allows you to modify the content of the adblock blacklist (%s)."

View file

@ -53,6 +53,9 @@ msgstr "Режим сохранения бекапа"
msgid "Blocklist Sources"
msgstr "Источники списков блокировки"
msgid "Blocklist not found!"
msgstr ""
msgid ""
"Builds an additional 'Jail' list (/tmp/adb_list.jail) to block access to all "
"domains except those listed in the whitelist file.<br />"
@ -186,9 +189,6 @@ msgstr "Полный путь к файлу Белого списка."
msgid "Input file not found, please check your configuration."
msgstr "Config файл не найден, настройте config файл."
msgid "Invalid domain specified!"
msgstr "Задан недопустимый домен!"
msgid "Last Run"
msgstr "Последнее время запуска"
@ -306,9 +306,8 @@ msgstr ""
msgid "Target directory for the generated blocklist 'adb_list.overall'."
msgstr "Назначить папку для создания списка блокировки 'adb_list.overall'."
msgid "The file size is too large for online editing in LuCI (&gt; 512 KB)."
msgid "The file size is too large for online editing in LuCI (&ge; 100 KB)."
msgstr ""
"Размер файла слишком большой, для онлайн редактирования в LuCI (&gt; 512 KB)."
msgid ""
"This form allows you to modify the content of the adblock blacklist (%s)."

View file

@ -39,9 +39,7 @@ msgstr ""
msgid "Blocklist Sources"
msgstr "Källor för blockeringslistor"
msgid ""
"Builds an additional 'Jail' list (/tmp/adb_list.jail) to block access to all "
"domains except those listed in the whitelist file.<br />"
msgid "Blocklist not found!"
msgstr ""
msgid "Categories"
@ -160,9 +158,6 @@ msgid "Input file not found, please check your configuration."
msgstr ""
"Inmatningsfilen kunde inte hittas, var vänlig kontrollera din konfiguration."
msgid "Invalid domain specified!"
msgstr "Ogiltig domän angiven!"
msgid "Last Run"
msgstr "Kördes senast"
@ -263,8 +258,8 @@ msgstr ""
msgid "Target directory for the generated blocklist 'adb_list.overall'."
msgstr ""
msgid "The file size is too large for online editing in LuCI (&gt; 512 KB)."
msgstr "Filstorleken är för stor för online-redigering i LuCi (&gt; 512 KB)."
msgid "The file size is too large for online editing in LuCI (&ge; 100 KB)."
msgstr ""
msgid ""
"This form allows you to modify the content of the adblock blacklist (%s)."

View file

@ -39,9 +39,7 @@ msgstr ""
msgid "Blocklist Sources"
msgstr ""
msgid ""
"Builds an additional 'Jail' list (/tmp/adb_list.jail) to block access to all "
"domains except those listed in the whitelist file.<br />"
msgid "Blocklist not found!"
msgstr ""
msgid "Categories"
@ -152,9 +150,6 @@ msgstr ""
msgid "Input file not found, please check your configuration."
msgstr ""
msgid "Invalid domain specified!"
msgstr ""
msgid "Last Run"
msgstr ""
@ -255,7 +250,7 @@ msgstr ""
msgid "Target directory for the generated blocklist 'adb_list.overall'."
msgstr ""
msgid "The file size is too large for online editing in LuCI (&gt; 512 KB)."
msgid "The file size is too large for online editing in LuCI (&ge; 100 KB)."
msgstr ""
msgid ""

View file

@ -16,7 +16,7 @@ msgstr ""
"Plural-Forms: nplurals=1; plural=0;\n"
msgid "'Jail' Blocklist Creation"
msgstr ""
msgstr "“Jail” 拦截名单创建"
msgid "-------"
msgstr "-------"
@ -48,14 +48,12 @@ msgid "Backup Directory"
msgstr "备份目录"
msgid "Backup Mode"
msgstr ""
msgstr "备份模式"
msgid "Blocklist Sources"
msgstr "拦截列表来源"
msgid ""
"Builds an additional 'Jail' list (/tmp/adb_list.jail) to block access to all "
"domains except those listed in the whitelist file.<br />"
msgid "Blocklist not found!"
msgstr ""
msgid "Categories"
@ -79,6 +77,7 @@ msgid ""
"Create compressed blocklist backups, they will be used in case of download "
"errors or during startup in backup mode."
msgstr ""
"创建压缩的拦截列表备份,它们将在下载错误或备份模式启动期间使用。"
msgid "DNS Backend (DNS Directory)"
msgstr "DNS 后端DNS 目录)"
@ -95,7 +94,7 @@ msgid ""
msgstr "启动期间不要自动更新 blocklists改用 blocklists 的备份。"
msgid "Download Utility"
msgstr ""
msgstr "下载工具"
msgid "Download Utility (SSL Library)"
msgstr "下载实用程序SSL 库)"
@ -110,10 +109,10 @@ msgid "Edit Whitelist"
msgstr "编辑白名单"
msgid "Email Notification"
msgstr ""
msgstr "Email 提醒"
msgid "Email Notification Count"
msgstr ""
msgstr "Email 提醒计数"
msgid "Enable Adblock"
msgstr "启用 Adblock"
@ -125,6 +124,7 @@ msgid ""
"Enable memory intense overall sort / duplicate removal on low memory devices "
"(&lt; 64 MB free RAM)"
msgstr ""
"在低内存设备上启用积极的内存整体排序/重复移除(&lt; 64 MB 空闲内存)"
msgid "Enable verbose debug logging in case of any processing error."
msgstr "在出现任何处理错误的情况下启用详细调试日志记录。"
@ -136,25 +136,29 @@ msgid "Extra Options"
msgstr "额外选项"
msgid "Flush DNS Cache"
msgstr ""
msgstr "清空 DNS 缓存"
msgid "Flush DNS Cache after adblock processing."
msgstr ""
msgstr "在 adblock 进程启动后清空 DNS 缓存。"
msgid ""
"For SSL protected blocklist sources you need a suitable SSL library, e.g. "
"'libustream-ssl' or 'built-in'."
msgstr ""
"对受 SSL 保护的拦截列表源,您需要一个合适的 SSL 库,如 “libustream-ssl” 或 "
"“built-in”。"
msgid ""
"For further information <a href=\"%s\" target=\"_blank\">check the online "
"documentation</a>"
msgstr ""
"进一步信息<a href=\"%s\" target=\"_blank\">请访问在线文档"
msgid ""
"For further performance improvements you can raise this value, e.g. '8' or "
"'16' should be safe."
msgstr ""
"为了进一步提高性能您可以提高此值例如8 或 16 应该是安全的。"
msgid "Force Local DNS"
msgstr "强制本地 DNS"
@ -163,14 +167,11 @@ msgid "Force Overall Sort"
msgstr "强制整体排序"
msgid "Full path to the whitelist file."
msgstr ""
msgstr "白名单文件的全路径。"
msgid "Input file not found, please check your configuration."
msgstr "输入文件未找到,请检查您的配置。"
msgid "Invalid domain specified!"
msgstr "无效域名!"
msgid "Last Run"
msgstr "最后运行"
@ -178,6 +179,7 @@ msgid ""
"List of available network interfaces. Usually the startup will be triggered "
"by the 'wan' interface.<br />"
msgstr ""
"可用网络接口列表。通常启动将由 “wan” 接口触发。<br />"
msgid ""
"List of supported DNS backends with their default list export directory.<br /"
@ -185,13 +187,13 @@ msgid ""
msgstr "支持的 DNS 后端列表及其默认列表导出目录。<br />"
msgid "List of supported and fully pre-configured download utilities."
msgstr ""
msgstr "支持和完全预配置的下载工具列表。"
msgid "Loading"
msgstr "加载中"
msgid "Max. Download Queue"
msgstr ""
msgstr "最大下载队列"
msgid "No"
msgstr "否"
@ -201,7 +203,7 @@ msgid ""
msgstr "在默认设置并不适合您时的额外选项。"
msgid "Overall Domains"
msgstr ""
msgstr "域名总览"
msgid "Overview"
msgstr "总览"
@ -230,6 +232,7 @@ msgid ""
"Raise the minimum email notification count, to get emails if the overall "
"count is less or equal to the given limit (default 0),<br />"
msgstr ""
"如果总数小于或等于给定限制(默认为 0请提高最小电子邮件通知数以获取电子邮件。"
msgid "Redirect all DNS queries from 'lan' zone to the local resolver."
msgstr "将所有 DNS 查询从“lan”区域重定向到本地解析器。"
@ -250,11 +253,13 @@ msgid ""
"Send notification emails in case of a processing error or if domain count is "
"&le; 0.<br />"
msgstr ""
"如果发生错误或域计数 &le; 0发送通知电子邮件。<br />"
msgid ""
"Size of the download queue to handle downloads &amp; list processing in "
"parallel (default '4').<br />"
msgstr ""
"处理下载队列的大小 amp; 并行处理列表(默认 “4”。<br />"
msgid "Startup Trigger"
msgstr "启动触发器"
@ -269,12 +274,14 @@ msgid ""
"Target directory for adblock backups. Please use only non-volatile disks, e."
"g. an external usb stick."
msgstr ""
"adblock 备份的目标目录。 请仅使用非易失性磁盘,例如:一个外置 U 盘。"
msgid "Target directory for the generated blocklist 'adb_list.overall'."
msgstr "生成的 blocklist 'adb_list.overall'的目标目录。"
msgid "The file size is too large for online editing in LuCI (&gt; 512 KB)."
msgstr "文件大小太大,无法在 LuCI&gt; 512 KB中进行在线编辑。"
msgid "The file size is too large for online editing in LuCI (&ge; 100 KB)."
msgstr ""
"文件过大,无法使用 LuCI 的在线编辑(&ge; 100 KB。"
msgid ""
"This form allows you to modify the content of the adblock blacklist (%s)."
@ -319,7 +326,7 @@ msgid "Waiting for command to complete..."
msgstr "正在执行命令..."
msgid "Whitelist File"
msgstr ""
msgstr "白名单文件"
msgid "Yes"
msgstr "是"
@ -328,6 +335,7 @@ msgid ""
"You can use this restrictive blocklist manually e.g. for guest wifi or "
"kidsafe configurations."
msgstr ""
"您可以手动使用此限制性拦截列表,例如:为客人提供 wifi 或 kidsafe 配置。"
msgid "disabled"
msgstr "已禁用"
@ -335,7 +343,7 @@ msgstr "已禁用"
msgid ""
"e.g. to receive an email notification with every adblock update set this "
"value to 150000."
msgstr ""
msgstr "例如:要接收每个 adblock 更新的电子邮件通知时将此值设置为150000。"
msgid "enabled"
msgstr "已启用"
@ -350,7 +358,18 @@ msgid "paused"
msgstr "已暂停"
msgid "running"
msgstr ""
msgstr "运行中"
#~ msgid "Invalid domain specified!"
#~ msgstr "无效域名!"
#~ msgid "Available blocklist sources."
#~ msgstr "可用的 blocklist 来源。"
#~ msgid ""
#~ "List URLs and Shallalist category selections are configurable in the "
#~ "'Advanced' section.<br />"
#~ msgstr "列表 URL 和 Shallalist 类别选择可在“高级”选项卡中配置。<br />"
#~ msgid "Available blocklist sources."
#~ msgstr "可用的 blocklist 来源。"

View file

@ -53,9 +53,7 @@ msgstr ""
msgid "Blocklist Sources"
msgstr "攔截列表來源"
msgid ""
"Builds an additional 'Jail' list (/tmp/adb_list.jail) to block access to all "
"domains except those listed in the whitelist file.<br />"
msgid "Blocklist not found!"
msgstr ""
msgid "Categories"
@ -168,9 +166,6 @@ msgstr ""
msgid "Input file not found, please check your configuration."
msgstr "輸入檔案未找到,請檢查您的配置。"
msgid "Invalid domain specified!"
msgstr "無效域名!"
msgid "Last Run"
msgstr "最後執行"
@ -273,8 +268,8 @@ msgstr ""
msgid "Target directory for the generated blocklist 'adb_list.overall'."
msgstr "生成的 blocklist 'adb_list.overall'的目標目錄。"
msgid "The file size is too large for online editing in LuCI (&gt; 512 KB)."
msgstr "檔案大小太大,無法在 LuCI&gt; 512 KB中進行線上編輯。"
msgid "The file size is too large for online editing in LuCI (&ge; 100 KB)."
msgstr ""
msgid ""
"This form allows you to modify the content of the adblock blacklist (%s)."

View file

@ -11,9 +11,9 @@ LUCI_DESCRIPTION:=Provides Web UI (found under System/Advanced Reboot) to reboot
an altnerative partition. Also provides Web UI to shut down (power off) your device. Supported dual-partition\
routers are listed at https://github.com/stangri/openwrt-luci/blob/luci-app-advanced-reboot/applications/luci-app-advanced-reboot/README.md
LUCI_DEPENDS:=+luci
LUCI_DEPENDS:=+luci-mod-admin-full
LUCI_PKGARCH:=all
PKG_RELEASE:=27
PKG_RELEASE:=32
include ../../luci.mk

View file

@ -14,6 +14,7 @@ Currently supported dual-partition devices include:
- Linksys WRT1900ACv2
- Linksys WRT1900ACS
- Linksys WRT3200ACM
- Linksys WRT32X
- ZyXEL NBG6817
If you're interested in having your device supported, please post in [LEDE Project Forum Support Thread](https://forum.lede-project.org/t/web-ui-to-reboot-to-another-partition-dual-partition-routers/3423).
@ -34,4 +35,4 @@ opkg install luci-app-advanced-reboot
- Some devices allow you to trigger reboot to an alternative partition by interrupting boot 3 times in a row (by resetting/switching off the device or pulling power). As these methods might be different for different devices, do your own homework.
## Thanks
I'd like to thank everyone who helped create, test and troubleshoot this package. Without contributions from [@hnyman](https://github.com/hnyman), [@jpstyves](https://github.com/jpstyves) and [@slh](https://github.com/pkgadd) it wouldn't have been possible.
I'd like to thank everyone who helped create, test and troubleshoot this package. Without help from [@hnyman](https://github.com/hnyman), [@jpstyves](https://github.com/jpstyves) and many contributions from [@slh](https://github.com/pkgadd) it wouldn't have been possible.

View file

@ -3,25 +3,26 @@
module("luci.controller.advanced_reboot", package.seeall)
-- device_name, board_name, part1, part2, offset, env_var_1, value_1_1, value_1_2, env_var_2, value_2_1, value_2_2
devices = {
-- deviceName, boardName, partition1, partition2, offset, envVar1, envVar1Value1, envVar1Value2, envVar2, envVar2Value1, envVar2Value2
{"Linksys EA3500", "linksys-audi", "mtd3", "mtd5", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"},
{"Linksys E4200v2/EA4500", "linksys-viper", "mtd3", "mtd5", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"},
{"Linksys EA8500", "ea8500", "mtd13", "mtd15", 32, "boot_part", 1, 2},
-- {"Linksys EA9500", "linksys,panamera", "mtd3", "mtd6", 28, "boot_part", 1, 2},
-- {"Linksys EA9500", "linksys-panamera", "mtd3", "mtd6", 28, "boot_part", 1, 2},
{"Linksys WRT1200AC", "linksys-caiman", "mtd4", "mtd6", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"},
{"Linksys WRT1900AC", "linksys-mamba", "mtd4", "mtd6", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"},
{"Linksys WRT1900ACv2", "linksys-cobra", "mtd4", "mtd6", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"},
{"Linksys WRT1900ACS", "linksys-shelby", "mtd4", "mtd6", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"},
{"Linksys WRT3200ACM", "linksys-rango", "mtd5", "mtd7", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"},
{"ZyXEL NBG6817","nbg6817","mmcblk0p4","mmcblk0p7",32,nil,255,1}
{"Linksys WRT32X", "linksys-venom", "mtd5", "mtd7", nil, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"},
{"ZyXEL NBG6817","nbg6817","mmcblk0p4","mmcblk0p7", 32, nil, 255, 1}
}
errorMessage = ""
device_board_name = luci.util.trim(luci.sys.exec("cat /tmp/sysinfo/board_name"))
errorMessage = nil
rom_board_name = luci.util.trim(luci.sys.exec("cat /tmp/sysinfo/board_name"))
for i=1, #devices do
table_board_name = devices[i][2]:gsub('%p','')
if device_board_name and device_board_name:gsub('%p',''):match(table_board_name) then
device_board_name = devices[i][2]:gsub('%p','')
if rom_board_name and rom_board_name:gsub('%p',''):match(device_board_name) then
device_name = devices[i][1]
partition_one_mtd = devices[i][3] or nil
partition_two_mtd = devices[i][4] or nil
@ -40,16 +41,20 @@ for i=1, #devices do
partition_two_label = luci.util.trim(luci.sys.exec("dd if=/dev/" .. partition_two_mtd .. " bs=1 skip=" .. partition_skip .. " count=25" .. " 2>/dev/null"))
n, partition_two_version = string.match(partition_two_label, '(Linux)-([%d|.]+)')
end
if string.find(partition_one_label, "LEDE") then partition_one_os = "LEDE" end
if string.find(partition_one_label, "OpenWrt") then partition_one_os = "OpenWrt" end
if string.find(partition_one_label, "Linksys") then partition_one_os = "Linksys" end
if string.find(partition_two_label, "LEDE") then partition_two_os = "LEDE" end
if string.find(partition_two_label, "OpenWrt") then partition_two_os = "OpenWrt" end
if string.find(partition_two_label, "Linksys") then partition_two_os = "Linksys" end
if partition_one_label and string.find(partition_one_label, "LEDE") then partition_one_os = "LEDE" end
if partition_one_label and string.find(partition_one_label, "OpenWrt") then partition_one_os = "OpenWrt" end
if partition_one_label and string.find(partition_one_label, "Linksys") then partition_one_os = "Linksys" end
if partition_two_label and string.find(partition_two_label, "LEDE") then partition_two_os = "LEDE" end
if partition_two_label and string.find(partition_two_label, "OpenWrt") then partition_two_os = "OpenWrt" end
if partition_two_label and string.find(partition_two_label, "Linksys") then partition_two_os = "Linksys" end
if device_name and device_name == "ZyXEL NBG6817" then
if not partition_one_os then partition_one_os = "ZyXEL" end
if not partition_two_os then partition_two_os = "ZyXEL" end
end
if device_name and device_name == "Linksys WRT32X" then
if not partition_one_os then partition_one_os = "Unknown/Compressed" end
if not partition_two_os then partition_two_os = "Unknown/Compressed" end
end
if not partition_one_os then partition_one_os = "Unknown" end
if not partition_two_os then partition_two_os = "Unknown" end
if partition_one_os and partition_one_version then partition_one_os = partition_one_os .. " (Linux " .. partition_one_version .. ")" end
@ -75,7 +80,6 @@ end
function index()
entry({"admin", "system", "advanced_reboot"}, template("advanced_reboot/advanced_reboot"), _("Advanced Reboot"), 90)
entry({"admin", "system", "advanced_reboot", "reboot"}, post("action_reboot"))
-- if device_name then entry({"admin", "system", "advanced_reboot", "altreboot"}, post("action_altreboot")) end
entry({"admin", "system", "advanced_reboot", "alternative_reboot"}, post("action_altreboot"))
entry({"admin", "system", "advanced_reboot", "power_off"}, post("action_poweroff"))
end
@ -93,18 +97,10 @@ end
function action_altreboot()
local uci = require "luci.model.uci".cursor()
local zyxelFlagPartition, zyxelBootFlag, zyxelNewBootFlag, errorCode, curEnvSetting, newEnvSetting
errorMessage = ""
errorMessage = nil
errorCode = 0
if luci.http.formvalue("cancel") then
luci.http.redirect(luci.dispatcher.build_url('admin/system/advanced_reboot'))
-- luci.template.render("advanced_reboot/advanced_reboot",{
-- device_name=device_name,
-- boot_envvar1_partition_one=boot_envvar1_partition_one,
-- partition_one_os=partition_one_os,
-- boot_envvar1_partition_two=boot_envvar1_partition_two,
-- partition_two_os=partition_two_os,
-- current_partition=current_partition,
-- errorMessage = luci.i18n.translate("Alternative reboot cancelled.")})
return
end
local step = tonumber(luci.http.formvalue("step") or 1)
@ -161,7 +157,7 @@ function action_altreboot()
end
end
end
if errorMessage == "" then
if not errorMessage then
luci.template.render("admin_system/applyreboot", {
title = luci.i18n.translate("Rebooting..."),
msg = luci.i18n.translate("The system is rebooting to an alternative partition now.<br /> DO NOT POWER OFF THE DEVICE!<br /> Wait a few minutes before you try to reconnect. It might be necessary to renew the address of your computer to reach the device again, depending on your settings."),
@ -170,6 +166,7 @@ function action_altreboot()
luci.sys.reboot()
else
luci.template.render("advanced_reboot/advanced_reboot",{
rom_board_name=rom_board_name,
device_name=device_name,
boot_envvar1_partition_one=boot_envvar1_partition_one,
partition_one_os=partition_one_os,

View file

@ -21,24 +21,24 @@
<%- if device_name then -%>
<fieldset class="cbi-section">
<legend><%=device_name%><%: Partitions%></legend>
<table class="cbi-section-table" id="partitions">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Partition%></th>
<th class="cbi-section-table-cell"><%:Status%></th>
<th class="cbi-section-table-cell"><%:Firmware/OS (Kernel)%></th>
<th class="cbi-section-table-cell"><%:Action%></th>
</tr>
<tr class="cbi-section-table-row">
<td>
<div class="table cbi-section-table" id="partitions">
<div class="tr cbi-section-table-titles">
<div class="th cbi-section-table-cell"><%:Partition%></div>
<div class="th cbi-section-table-cell"><%:Status%></div>
<div class="th cbi-section-table-cell"><%:Firmware/OS (Kernel)%></div>
<div class="th cbi-section-table-cell"><%:Action%></div>
</div>
<div class="tr cbi-section-table-row">
<div class="td">
<%=string.format("%X", boot_envvar1_partition_one)%>
</td>
<td>
</div>
<div class="td">
<%- if boot_envvar1_partition_one == current_partition then -%><%:Current%><%- else -%><%:Alternative%><%- end -%>
</td>
<td>
</div>
<div class="td">
<%=partition_one_os%>
</td>
<td>
</div>
<div class="td">
<%- if boot_envvar1_partition_one == current_partition then -%>
<form method="post" action="<%=url('admin/system/advanced_reboot/reboot')%>">
<input type="hidden" name="token" value="<%=token%>" />
@ -50,19 +50,19 @@
<input id="altreboot-button" type="submit" class="cbi-button cbi-button-apply" value="<%:Reboot to alternative partition...%>" />
</form>
<%- end -%>
</td>
</tr>
<tr class="cbi-section-table-row">
<td>
</div>
</div>
<div class="tr cbi-section-table-row">
<div class="td">
<%=string.format("%X", boot_envvar1_partition_two)%>
</td>
<td>
</div>
<div class="td">
<%- if boot_envvar1_partition_two == current_partition then -%><%:Current%><%- else -%><%:Alternative%><%- end -%>
</td>
<td>
</div>
<div class="td">
<%=partition_two_os%>
</td>
<td>
</div>
<div class="td">
<%- if boot_envvar1_partition_two == current_partition then -%>
<form method="post" action="<%=url('admin/system/advanced_reboot/reboot')%>">
<input type="hidden" name="token" value="<%=token%>" />
@ -74,12 +74,16 @@
<input id="altreboot-button" type="submit" class="cbi-button cbi-button-apply" value="<%:Reboot to alternative partition...%>" />
</form>
<%- end -%>
</td>
</tr>
</table>
</div>
</div>
</div>
</fieldset>
<%- else -%>
<p class="alert-message warning"><%:Warning: This system does not have two partitions!%></p>
<%- if rom_board_name then -%>
<p class="alert-message warning"><%=pcdata(translatef("Warning: Device (%s) is unknown or isn't a dual-partition device!", rom_board_name))%></p>
<%- else -%>
<p class="alert-message warning"><%:Warning: Unable to obtain device information!%></p>
<%- end -%>
<%- end -%>
<hr />

View file

@ -1,6 +1,9 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8"
msgid ") is unknown or isn't a dual-partition device!"
msgstr ""
msgid "Action"
msgstr ""
@ -10,9 +13,6 @@ msgstr ""
msgid "Alternative"
msgstr ""
msgid "Alternative reboot cancelled."
msgstr ""
msgid "Cancel"
msgstr ""
@ -113,14 +113,17 @@ msgid ""
"device."
msgstr ""
msgid "Warning: There are unsaved changes that will get lost on reboot!"
msgid "Warning: Device ("
msgstr ""
msgid "Warning: This system does not have two partitions!"
msgid "Warning: There are unsaved changes that will get lost on reboot!"
msgstr ""
msgid "Warning: This system does not support powering off!"
msgstr ""
msgid "Warning: Unable to obtain device information!"
msgstr ""
msgid "to"
msgstr ""

View file

@ -7,29 +7,21 @@
if (st && tb && tx)
{
/* clear all rows */
while( tb.rows.length > 1 )
tb.deleteRow(1);
while (tb.firstElementChild !== tb.lastElementChild)
tb.removeChild(tb.lastElementChild);
for( var i = 0; i < st.leases.length; i++ )
for (var i = 0; i < st.leases.length; i++)
{
var tr = tb.insertRow(-1);
tr.className = 'cbi-section-table-row cbi-rowstyle-' + ((i % 2) + 1);
tr.insertCell(-1).innerHTML = st.leases[i].addr;
tr.insertCell(-1).innerHTML = String.format('%t', st.leases[i].age);
tb.appendChild(E('<div class="tr cbi-section-table-row cbi-rowstyle-%d">'.format((i % 2) + 1), [
E('<div class="td">', st.leases[i].addr),
E('<div class="td">', '%t'.format(st.leases[i].age))
]));
}
if( tb.rows.length == 1 )
{
var tr = tb.insertRow(-1);
tr.className = 'cbi-section-table-row';
if (tb.firstElementChild === tb.lastElementChild)
tb.appendChild(E('<div class="tr cbi-section-table-row"><div class="td"><em><br /><%:There are no active leases.%></em></div></div>'));
var td = tr.insertCell(-1);
td.colSpan = 2;
td.innerHTML = '<em><br /><%:There are no active leases.%></em>';
}
if( st.uid == '00:00:00:00:00:00:00:00' )
if (st.uid == '00:00:00:00:00:00:00:00')
tx.innerHTML = '<%:The AHCP Service is not running.%>';
else
tx.innerHTML = String.format('<%:The AHCP Service is running with ID %s.%>', st.uid);
@ -41,13 +33,13 @@
<fieldset class="cbi-section">
<legend><%:Active AHCP Leases%></legend>
<p id="ahcpd_status_text"></p>
<table class="cbi-section-table" id="ahcpd_status_table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Address%></th>
<th class="cbi-section-table-cell"><%:Age%></th>
</tr>
<tr class="cbi-section-table-row">
<td colspan="5"><em><br /><%:Collecting data...%></em></td>
</tr>
</table>
<div class="table cbi-section-table" id="ahcpd_status_table">
<div class="tr cbi-section-table-titles">
<div class="th cbi-section-table-cell"><%:Address%></div>
<div class="th cbi-section-table-cell"><%:Age%></div>
</div>
<div class="tr cbi-section-table-row">
<div class="td" colspan="5"><em><br /><%:Collecting data...%></em></div>
</div>
</div>
</fieldset>

View file

@ -58,7 +58,6 @@
<form method="post" action="<%=url('admin/asterisk/dialplans')%>" enctype="multipart/form-data">
<div>
<script type="text/javascript" src="/luci-static/resources/cbi.js"></script>
<input type="hidden" name="cbi.submit" value="1" />
<input type="submit" value="Save" class="hidden" />
</div>
@ -79,23 +78,23 @@
<% for i, plan in pairs(ast.dialplan.plans()) do %>
<div class="cbi-section-node">
<table class="cbi-section-table">
<tr class="cbi-section-table-titles">
<th style="text-align: left; padding: 3px" class="cbi-section-table-cell">
<div class="table cbi-section-table">
<div class="tr cbi-section-table-titles">
<div style="text-align: left; padding: 3px" class="th cbi-section-table-cell">
<big>Dialplan <em><%=plan.name%></em></big>
</th>
<td>
</div>
<div class="td">
<a href="<%=url('admin/asterisk/dialplans')%>?delplan=<%=plan.name%>">
<img style="border:none" alt="Remove this dialplan" title="Remove this dialplan" src="/luci-static/resources/cbi/remove.gif" />
</a>
</td>
</tr>
</div>
</div>
<!-- dialzones -->
<% local zones_used = { }; local row = 0 %>
<% for i, zone in ipairs(plan.zones) do zones_used[zone.name] = true %>
<tr class="cbi-section-table-row <%=rowstyle(row)%>">
<td style="text-align: left; padding: 3px" class="cbi-section-table-cell">
<div class="tr cbi-section-table-row <%=rowstyle(row)%>">
<div style="text-align: left; padding: 3px" class="td cbi-section-table-cell">
<strong>&#x2514; Dialzone <em><%=zone.name%></em></strong> (<%=zone.description%>)
<p style="padding-left: 1em; margin-bottom:0">
Lines:
@ -107,24 +106,24 @@
Matches:
<%=format_matches(zone)%>
</p>
</td>
<td style="width:5%" class="cbi-value-field">
</div>
<div style="width:5%" class="td cbi-value-field">
<a href="<%=url('admin/asterisk/dialplans/out', zone.name)%>">
<img style="border:none" alt="Edit dialzone" title="Edit dialzone" src="/luci-static/resources/cbi/edit.gif" />
</a>
<a href="<%=url('admin/asterisk/dialplans')%>?delzone.<%=plan.name%>=<%=zone.name%>">
<img style="border:none" alt="Remove from this dialplan" title="Remove from this dialplan" src="/luci-static/resources/cbi/remove.gif" />
</a>
</td>
</tr>
</div>
</div>
<% row = row + 1; end %>
<!-- /dialzones -->
<!-- voicemail -->
<% local boxes_used = { } %>
<% for ext, box in luci.util.kspairs(plan.voicemailboxes) do boxes_used[box.id] = true %>
<tr class="cbi-section-table-row <%=rowstyle(row)%>">
<td style="text-align: left; padding: 3px" class="cbi-section-table-cell">
<div class="tr cbi-section-table-row <%=rowstyle(row)%>">
<div style="text-align: left; padding: 3px" class="td cbi-section-table-cell">
<strong>&#x2514; Voicemailbox <em><%=box.id%></em></strong> (<%=box.name%>)
<p style="padding-left: 1em; margin-bottom:0">
Owner: <%=box.name%> |
@ -132,44 +131,44 @@
Pager: <%=#box.page > 0 and box.page or 'n/a'%><br />
Matches: <%=format_matches(ext)%>
</p>
</td>
<td style="width:5%" class="cbi-value-field">
</div>
<div style="width:5%" class="td cbi-value-field">
<a href="<%=url('admin/asterisk/voicemail/mailboxes')%>">
<img style="border:none" alt="Manage mailboxes ..." title="Manage mailboxes ..." src="/luci-static/resources/cbi/edit.gif" />
</a>
<a href="<%=url('admin/asterisk/dialplans')%>?delvbox.<%=plan.name%>=<%=ext%>">
<img style="border:none" alt="Remove from this dialplan" title="Remove from this dialplan" src="/luci-static/resources/cbi/remove.gif" />
</a>
</td>
</tr>
</div>
</div>
<% row = row + 1; end %>
<!-- /voicemail -->
<!-- meetme -->
<% local rooms_used = { } %>
<% for ext, room in luci.util.kspairs(plan.meetmerooms) do rooms_used[room.room] = true %>
<tr class="cbi-section-table-row <%=rowstyle(row)%>">
<td style="text-align: left; padding: 3px" class="cbi-section-table-cell">
<div class="tr cbi-section-table-row <%=rowstyle(row)%>">
<div style="text-align: left; padding: 3px" class="td cbi-section-table-cell">
<strong>&#x2514; MeetMe Room <em><%=room.room%></em></strong>
<% if room.description and #room.description > 0 then %> (<%=room.description%>)<% end %>
<p style="padding-left: 1em; margin-bottom:0">
Matches: <%=format_matches(ext)%>
</p>
</td>
<td style="width:5%" class="cbi-value-field">
</div>
<div style="width:5%" class="td cbi-value-field">
<a href="<%=url('admin/asterisk/meetme/rooms')%>">
<img style="border:none" alt="Manage conferences ..." title="Manage conferences ..." src="/luci-static/resources/cbi/edit.gif" />
</a>
<a href="<%=url('admin/asterisk/dialplans')%>?delmeetme.<%=plan.name%>=<%=ext%>">
<img style="border:none" alt="Remove from this dialplan" title="Remove from this dialplan" src="/luci-static/resources/cbi/remove.gif" />
</a>
</td>
</tr>
</div>
</div>
<% row = row + 1; end %>
<!-- /meetme -->
<tr class="cbi-section-table-row">
<td style="text-align: left; padding: 3px" class="cbi-section-table-cell" colspan="2">
<div class="tr cbi-section-table-row">
<div style="text-align: left; padding: 3px" class="td cbi-section-table-cell" colspan="2">
<hr style="margin-bottom:0.5em; border-width:0 0 1px 0" />
Add Dialzone:<br />
@ -213,10 +212,10 @@
<br /><br />
<input type="submit" class="cbi-button cbi-button-add" value="Add item &raquo;" title="Add item ..."/>
</td>
</tr>
</div>
</div>
</table>
</div>
<div class="cbi-section-create cbi-tblsection-create"></div>
</div>

View file

@ -49,7 +49,6 @@
<form method="post" action="<%=url('admin/asterisk/dialplans/zones')%>" enctype="multipart/form-data">
<div>
<script type="text/javascript" src="/luci-static/resources/cbi.js"></script>
<input type="hidden" name="cbi.submit" value="1" />
<input type="submit" value="Save" class="hidden" />
</div>
@ -66,59 +65,59 @@
<!-- tblsection -->
<fieldset class="cbi-section" id="cbi-asterisk-sip">
<div class="cbi-section-node">
<table class="cbi-section-table">
<tr class="cbi-section-table-titles">
<th style="text-align: left; padding: 3px" class="cbi-section-table-cell" colspan="6">
<div class="table cbi-section-table">
<div class="tr cbi-section-table-titles">
<div style="text-align: left; padding: 3px" class="th cbi-section-table-cell" colspan="6">
<h3>Dialzone Overview</h3>
</th>
</tr>
</div>
</div>
<tr class="cbi-section-table-descr">
<th style="width: 5%; text-align:right" class="cbi-section-table-cell">Name</th>
<th style="width: 5%; text-align:right" class="cbi-section-table-cell">Prepend</th>
<th style="width: 20%; text-align:left" class="cbi-section-table-cell">- Match</th>
<th style="text-align:left" class="cbi-section-table-cell">Trunk</th>
<th style="width: 35%; text-align:left" class="cbi-section-table-cell">Description</th>
<th style="width: 4%; text-align:left" class="cbi-section-table-cell"></th>
</tr>
<div class="tr cbi-section-table-descr">
<div style="width: 5%; text-align:right" class="th cbi-section-table-cell">Name</div>
<div style="width: 5%; text-align:right" class="th cbi-section-table-cell">Prepend</div>
<div style="width: 20%; text-align:left" class="th cbi-section-table-cell">- Match</div>
<div style="text-align:left" class="th cbi-section-table-cell">Trunk</div>
<div style="width: 35%; text-align:left" class="th cbi-section-table-cell">Description</div>
<div style="width: 4%; text-align:left" class="th cbi-section-table-cell"></div>
</div>
<% for i, rule in pairs(ast.dialzone.zones()) do %>
<tr class="cbi-section-table-row <%=rowstyle(i)%>">
<td style="text-align:right" class="cbi-value-field">
<div class="tr cbi-section-table-row <%=rowstyle(i)%>">
<div style="text-align:right" class="td cbi-value-field">
<%=rule.name%>
</td>
<td style="text-align:right" class="cbi-value-field">
</div>
<div style="text-align:right" class="td cbi-value-field">
<% for _ in ipairs(rule.matches) do %>
<%=rule.addprefix and digit_pattern(rule.addprefix)%>&#160;<br />
<% end %>
</td>
<td style="text-align:left" class="cbi-value-field">
</div>
<div style="text-align:left" class="td cbi-value-field">
<% for _, m in ipairs(rule.matches) do %>
<%=rule.localprefix and "%s " % digit_pattern(rule.localprefix)%>
<%=digit_pattern(m)%><br />
<% end %>
</td>
<td style="text-align:left" class="cbi-value-field">
</div>
<div style="text-align:left" class="td cbi-value-field">
<%=ast.tools.hyperlinks(
rule.trunks, function(v)
return luci.dispatcher.build_url("admin", "asterisk", "trunks", "%s") % v:lower()
end
)%>
</td>
<td style="text-align:left" class="cbi-value-field">
</div>
<div style="text-align:left" class="td cbi-value-field">
<%=rule.description or rule.name%>
</td>
<td style="text-align:left" class="cbi-value-field">
</div>
<div style="text-align:left" class="td cbi-value-field">
<a href="<%=url('admin/asterisk/dialplans/out', rule.name)%>">
<img style="border:none" alt="Edit entry" title="Edit entry" src="/luci-static/resources/cbi/edit.gif" />
</a>
<a href="<%=url('admin/asterisk/dialplans/zones')%>?delzone=<%=rule.name%>">
<img style="border:none" alt="Delete entry" title="Delete entry" src="/luci-static/resources/cbi/remove.gif" />
</a>
</td>
</tr>
</div>
</div>
<% end %>
</table>
</div>
<div class="cbi-section-create cbi-tblsection-create"></div>
</div>
<br />
@ -133,26 +132,26 @@
<br /><span style="color:red">Invalid name given!</span><br />
<% end -%>
<table>
<tr>
<td style="padding:3px">
<div class="table">
<div class="tr">
<div class="td" style="padding:3px">
<label for="create1">1) Name</label><br />
<input type="text" class="cbi-section-create-name" id="create1" name="newzone_name" style="width:200px" />
<br /><br />
<label for="create2">2) Number Match</label><br />
<input type="text" class="cbi-section-create-name" id="create2" name="newzone_match" style="width:200px" />
</td>
<td style="padding:3px">
</div>
<div class="td" style="padding:3px">
<label for="create3">3) Trunks</label><br />
<select class="cbi-input-select" multiple="multiple" id="create3" name="newzone_uses" size="4" style="width:200px">
<% for i, t in ipairs(find_trunks()) do %>
<option value="<%=t[1]%>"><%=t[2]%></option>
<% end %>
</select>
</td>
</tr>
</table>
</div>
</div>
</div>
<br />
<input type="submit" class="cbi-button cbi-button-add" name="newzone" value="Add entry" title="Add entry"/>

View file

@ -14,7 +14,8 @@ $Id$
local wa = require "luci.tools.webadmin"
local net = require "luci.model.network".init()
local ifaces = net:get_interfaces()
local sys = require "luci.sys"
local ifaces = sys.net:devices()
m = Map("bcp38", translate("BCP38"),
translate("This function blocks packets with private address destinations " ..
@ -37,10 +38,17 @@ a.rmempty = false
n = s:option(ListValue, "interface", translate("Interface name"), translate("Interface to apply the blocking to " ..
"(should be the upstream WAN interface)."))
for _, iface in ipairs(ifaces) do
if iface:is_up() then
n:value(iface:name())
end
if not (iface == "lo" or iface:match("^ifb.*")) then
local nets = net:get_interface(iface)
nets = nets and nets:get_networks() or {}
for k, v in pairs(nets) do
nets[k] = nets[k].sid
end
nets = table.concat(nets, ",")
n:value(iface, ((#nets > 0) and "%s (%s)" % {iface, nets} or iface))
end
end
n.rmempty = false

View file

@ -34,7 +34,6 @@
<%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript">//<![CDATA[
var stxhr = new XHR();

View file

@ -82,7 +82,6 @@ $Id$
<hr/>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript">//<![CDATA[
var capture_running = 0;

View file

@ -19,7 +19,8 @@ PKG_VERSION:=2.4.9
PKG_RELEASE:=3
PKG_LICENSE:=Apache-2.0
PKG_MAINTAINER:=Christian Schoenebeck <christian.schoenebeck@gmail.com>
PKG_MAINTAINER:=Christian Schoenebeck <christian.schoenebeck@gmail.com>, \
Ansuel Smith <ansuelsmth@gmail.com>
# LuCI specific settings
LUCI_TITLE:=LuCI Support for Dynamic DNS Client (ddns-scripts)

View file

@ -21,7 +21,6 @@ luci_helper = "/usr/lib/ddns/dynamic_dns_lucihelper.sh"
local srv_name = "ddns-scripts"
local srv_ver_min = "2.7.7" -- minimum version of service required
local srv_ver_cmd = luci_helper .. [[ -V | awk {'print $2'}]]
local app_name = "luci-app-ddns"
local app_title = "Dynamic DNS"
local app_version = "2.4.9-1"
@ -29,7 +28,6 @@ local app_version = "2.4.9-1"
function index()
local nxfs = require "nixio.fs" -- global definitions not available
local sys = require "luci.sys" -- in function index()
local ddns = require "luci.tools.ddns" -- ddns multiused functions
local muci = require "luci.model.uci"
-- no config create an empty one
@ -81,33 +79,40 @@ end
-- Standardized application/service functions
function app_title_main()
return [[<a href="javascript:alert(']]
.. I18N.translate("Version Information")
.. [[\n\n]] .. app_name
.. [[\n\t]] .. I18N.translate("Version") .. [[:\t]] .. app_version
.. [[\n\n]] .. srv_name .. [[ ]] .. I18N.translate("required") .. [[:]]
.. [[\n\t]] .. I18N.translate("Version") .. [[:\t]]
.. srv_ver_min .. [[ ]] .. I18N.translate("or higher")
.. [[\n\n]] .. srv_name .. [[ ]] .. I18N.translate("installed") .. [[:]]
.. [[\n\t]] .. I18N.translate("Version") .. [[:\t]]
.. (service_version() or I18N.translate("NOT installed"))
.. [[\n\n]]
.. [[')">]]
.. I18N.translate(app_title)
.. [[</a>]]
tmp = {}
tmp[#tmp+1] = [[<a href="javascript:alert(']]
tmp[#tmp+1] = I18N.translate("Version Information")
tmp[#tmp+1] = [[\n\n]] .. app_name
tmp[#tmp+1] = [[\n]] .. I18N.translate("Version") .. [[: ]] .. app_version
tmp[#tmp+1] = [[\n\n]] .. srv_name .. [[ ]] .. I18N.translate("required") .. [[:]]
tmp[#tmp+1] = [[\n]] .. I18N.translate("Version") .. [[: ]]
tmp[#tmp+1] = srv_ver_min .. [[ ]] .. I18N.translate("or higher")
tmp[#tmp+1] = [[\n\n]] .. srv_name .. [[ ]] .. I18N.translate("installed") .. [[:]]
tmp[#tmp+1] = [[\n]] .. I18N.translate("Version") .. [[: ]]
tmp[#tmp+1] = (service_version() or I18N.translate("NOT installed"))
tmp[#tmp+1] = [[\n\n]]
tmp[#tmp+1] = [[')">]]
tmp[#tmp+1] = I18N.translate(app_title)
tmp[#tmp+1] = [[</a>]]
return table.concat(tmp)
end
function service_version()
local ver = nil
ver = UTIL.exec(srv_ver_cmd)
if #ver > 0 then return ver end
IPKG.list_installed(srv_name, function(n, v, d)
if v and (#v > 0) then ver = v end
end
)
return ver
local srv_ver_cmd = luci_helper .. " -V | awk {'print $2'} "
local ver
if IPKG then
ver = IPKG.info(srv_name)[srv_name].Version
else
ver = UTIL.exec(srv_ver_cmd)
end
if ver and #ver > 0 then return ver or nil end
end
function service_ok()
return IPKG.compare_versions((service_version() or "0"), ">=", srv_ver_min)
end

View file

@ -172,7 +172,7 @@ local function _option_used(option, urlscript)
end
-- function to verify if option is valid
local function _option_validate(self, value)
local function _option_validate(self, value, optional)
-- section is globally defined here be calling agrument (see above)
local fusev6 = usev6:formvalue(section) or "0"
local fsvc4 = svc4:formvalue(section) or "-"
@ -204,6 +204,7 @@ local function _option_validate(self, value)
if used < 1 then return "" end
-- needed but no data then return error
if not value or (#value == 0) then
if optional then return nil end
return nil, err_tab_basic(self) .. translate("missing / required")
end
return value
@ -292,6 +293,10 @@ function luh.parse(self, section, novld)
end
-- use_ipv6 -- ################################################################
--We call it globally as it's called 11 times even outside specific function, saves 11 os.execute slow command!
local has_ipv6 = DDNS.env_info("has_ipv6")
usev6 = ns:taboption("basic", ListValue, "use_ipv6",
translate("IP address version"),
translate("Defines which IP address 'IPv4/IPv6' is send to the DDNS provider") )
@ -300,16 +305,16 @@ usev6.default = "0"
usev6:value("0", translate("IPv4-Address") )
function usev6.cfgvalue(self, section)
local value = AbstractValue.cfgvalue(self, section) or "0"
if DDNS.has_ipv6 or (value == "1" and not DDNS.has_ipv6) then
if has_ipv6 or (value == "1" and not has_ipv6) then
self:value("1", translate("IPv6-Address") )
end
if value == "1" and not DDNS.has_ipv6 then
if value == "1" and not has_ipv6 then
self.description = err_ipv6_basic
end
return value
end
function usev6.validate(self, value)
if (value == "1" and DDNS.has_ipv6) or value == "0" then
if (value == "1" and has_ipv6) or value == "0" then
return value
end
return nil, err_tab_basic(self) .. err_ipv6_plain
@ -360,7 +365,7 @@ svc6 = ns:taboption("basic", ListValue, "ipv6_service_name",
translate("DDNS Service provider") .. " [IPv6]" )
svc6.default = "-"
svc6:depends("use_ipv6", "1") -- only show on IPv6
if not DDNS.has_ipv6 then
if not has_ipv6 then
svc6.description = err_ipv6_basic
end
function svc6.cfgvalue(self, section)
@ -374,7 +379,7 @@ function svc6.cfgvalue(self, section)
end
function svc6.validate(self, value)
if usev6:formvalue(section) == "1" then -- do only on IPv6
if DDNS.has_ipv6 then return value end
if has_ipv6 then return value end
return nil, err_tab_basic(self) .. err_ipv6_plain
else
return "" -- suppress validate error
@ -509,18 +514,18 @@ pe = ns:taboption("basic", Value, "param_enc",
translate("Optional Encoded Parameter"),
translate("Optional: Replaces [PARAMENC] in Update-URL (URL-encoded)") )
function pe.validate(self, value)
return _option_validate(self, value)
return _option_validate(self, value, true)
end
function pe.parse(self, section, novld)
DDNS.value_parse(self, section, novld)
end
-- IPv4/IPv6 - param_enc -- ###################################################
-- IPv4/IPv6 - param_opt -- ###################################################
po = ns:taboption("basic", Value, "param_opt",
translate("Optional Parameter"),
translate("Optional: Replaces [PARAMOPT] in Update-URL (NOT URL-encoded)") )
function po.validate(self, value)
return _option_validate(self, value)
return _option_validate(self, value, true)
end
function po.parse(self, section, novld)
DDNS.value_parse(self, section, novld)
@ -586,13 +591,17 @@ end
svc6:value("-", translate("-- custom --") )
-- IPv4/IPv6 - use_https -- ###################################################
if DDNS.has_ssl or ( ( m:get(section, "use_https") or "0" ) == "1" ) then
--We call it globally as it's called 4 times outside specific function.
local has_ssl = DDNS.env_info("has_ssl")
if has_ssl or ( ( m:get(section, "use_https") or "0" ) == "1" ) then
https = ns:taboption("basic", Flag, "use_https",
translate("Use HTTP Secure") )
https.orientation = "horizontal"
function https.cfgvalue(self, section)
local value = AbstractValue.cfgvalue(self, section)
if not DDNS.has_ssl and value == "1" then
if not has_ssl and value == "1" then
self.description = bold_on .. font_red ..
translate("HTTPS not supported") .. font_off .. "<br />" ..
translate("please disable") .. " !" .. bold_off
@ -602,7 +611,7 @@ if DDNS.has_ssl or ( ( m:get(section, "use_https") or "0" ) == "1" ) then
return value
end
function https.validate(self, value)
if (value == "1" and DDNS.has_ssl ) or value == "0" then return value end
if (value == "1" and has_ssl ) or value == "0" then return value end
return nil, err_tab_basic(self) .. translate("HTTPS not supported") .. " !"
end
function https.write(self, section, value)
@ -616,7 +625,7 @@ if DDNS.has_ssl or ( ( m:get(section, "use_https") or "0" ) == "1" ) then
end
-- IPv4/IPv6 - cacert -- ######################################################
if DDNS.has_ssl then
if has_ssl then
cert = ns:taboption("basic", Value, "cacert",
translate("Path to CA-Certificate"),
translate("directory or path/file") .. "<br />" ..
@ -706,7 +715,7 @@ src6:value("network", translate("Network"))
src6:value("web", translate("URL"))
src6:value("interface", translate("Interface"))
src6:value("script", translate("Script"))
if not DDNS.has_ipv6 then
if not has_ipv6 then
src6.description = err_ipv6_other
end
function src6.cfgvalue(self, section)
@ -715,7 +724,7 @@ end
function src6.validate(self, value)
if usev6:formvalue(section) ~= "1" then
return "" -- ignore on IPv4 selected
elseif not DDNS.has_ipv6 then
elseif not has_ipv6 then
return nil, err_tab_adv(self) .. err_ipv6_plain
elseif not _verify_ip_source() then
return nil, err_tab_adv(self) ..
@ -794,7 +803,7 @@ ipn6 = ns:taboption("advanced", ListValue, "ipv6_network",
ipn6:depends("ipv6_source", "network")
ipn6.default = "wan6"
WADM.cbi_add_networks(ipn6)
if DDNS.has_ipv6 then
if has_ipv6 then
ipn6.description = translate("Defines the network to read systems IPv6-Address from")
else
ipn6.description = err_ipv6_other
@ -808,7 +817,7 @@ function ipn6.validate(self, value)
-- ignore if IPv4 selected OR
-- ignore everything except "network"
return ""
elseif DDNS.has_ipv6 then
elseif has_ipv6 then
return value
else
return nil, err_tab_adv(self) .. err_ipv6_plain
@ -881,7 +890,7 @@ iurl6 = ns:taboption("advanced", Value, "ipv6_url",
translate("URL to detect") .. " [IPv6]" )
iurl6:depends("ipv6_source", "web")
iurl6.default = "http://checkipv6.dyndns.com"
if DDNS.has_ipv6 then
if has_ipv6 then
iurl6.description = translate("Defines the Web page to read systems IPv6-Address from")
else
iurl6.description = err_ipv6_other
@ -895,7 +904,7 @@ function iurl6.validate(self, value)
-- ignore if IPv4 selected OR
-- ignore everything except "web"
return ""
elseif not DDNS.has_ipv6 then
elseif not has_ipv6 then
return nil, err_tab_adv(self) .. err_ipv6_plain
elseif not value or #value == 0 then
return nil, err_tab_adv(self) .. translate("missing / required")
@ -1051,7 +1060,7 @@ eif6:depends("ipv6_source", "web")
eif6:depends("ipv6_source", "script")
eif6.default = "wan6"
WADM.cbi_add_networks(eif6)
if not DDNS.has_ipv6 then
if not has_ipv6 then
eif6.description = err_ipv6_other
else
eif6.description = translate("Network on which the ddns-updater scripts will be started")
@ -1065,7 +1074,7 @@ function eif6.validate(self, value)
or fsrc6 == "network"
or fsrc6 == "interface" then
return "" -- ignore IPv4, network, interface
elseif not DDNS.has_ipv6 then
elseif not has_ipv6 then
return nil, err_tab_adv(self) .. err_ipv6_plain
else
return value
@ -1084,10 +1093,13 @@ function eif6.write(self, section, value)
end
function eif6.parse(self, section, novld)
DDNS.value_parse(self, section, novld)
end
end
-- IPv4/IPv6 - bind_network -- ################################################
if DDNS.has_bindnet or ( ( m:get(section, "bind_network") or "" ) ~= "" ) then
local has_bindnet = DDNS.env_info("has_bindnet")
if has_bindnet or ( ( m:get(section, "bind_network") or "" ) ~= "" ) then
bnet = ns:taboption("advanced", ListValue, "bind_network",
translate("Bind Network") )
bnet:depends("ipv4_source", "web")
@ -1097,7 +1109,7 @@ if DDNS.has_bindnet or ( ( m:get(section, "bind_network") or "" ) ~= "" ) then
WADM.cbi_add_networks(bnet)
function bnet.cfgvalue(self, section)
local value = AbstractValue.cfgvalue(self, section)
if not DDNS.has_bindnet and value ~= "" then
if not has_bindnet and value ~= "" then
self.description = bold_on .. font_red ..
translate("Binding to a specific network not supported") .. font_off .. "<br />" ..
translate("please set to 'default'") .. " !" .. bold_off
@ -1108,7 +1120,7 @@ if DDNS.has_bindnet or ( ( m:get(section, "bind_network") or "" ) ~= "" ) then
return value
end
function bnet.validate(self, value)
if ( (value ~= "") and DDNS.has_bindnet ) or (value == "") then return value end
if ( (value ~= "") and has_bindnet ) or (value == "") then return value end
return nil, err_tab_adv(self) .. translate("Binding to a specific network not supported") .. " !"
end
function bnet.parse(self, section, novld)
@ -1119,13 +1131,16 @@ end
-- IPv4 + IPv6 - force_ipversion -- ###########################################
-- optional to force wget/curl and host to use only selected IP version
-- command parameter "-4" or "-6"
if DDNS.has_forceip or ( ( m:get(section, "force_ipversion") or "0" ) ~= "0" ) then
local has_forceip = DDNS.env_info("has_forceip")
if has_forceip or ( ( m:get(section, "force_ipversion") or "0" ) ~= "0" ) then
fipv = ns:taboption("advanced", Flag, "force_ipversion",
translate("Force IP Version") )
fipv.orientation = "horizontal"
function fipv.cfgvalue(self, section)
local value = AbstractValue.cfgvalue(self, section)
if not DDNS.has_forceip and value ~= "0" then
if not has_forceip and value ~= "0" then
self.description = bold_on .. font_red ..
translate("Force IP Version not supported") .. font_off .. "<br />" ..
translate("please disable") .. " !" .. bold_off
@ -1135,14 +1150,17 @@ if DDNS.has_forceip or ( ( m:get(section, "force_ipversion") or "0" ) ~= "0" ) t
return value
end
function fipv.validate(self, value)
if (value == "1" and DDNS.has_forceip) or value == "0" then return value end
if (value == "1" and has_forceip) or value == "0" then return value end
return nil, err_tab_adv(self) .. translate("Force IP Version not supported")
end
end
-- IPv4 + IPv6 - dns_server -- ################################################
-- optional DNS Server to use resolving my IP
if DDNS.has_dnsserver or ( ( m:get(section, "dns_server") or "" ) ~= "" ) then
local has_dnsserver = DDNS.env_info("has_dnsserver")
if has_dnsserver or ( ( m:get(section, "dns_server") or "" ) ~= "" ) then
dns = ns:taboption("advanced", Value, "dns_server",
translate("DNS-Server"),
translate("OPTIONAL: Use non-default DNS-Server to detect 'Registered IP'.") .. "<br />" ..
@ -1152,7 +1170,7 @@ if DDNS.has_dnsserver or ( ( m:get(section, "dns_server") or "" ) ~= "" ) then
-- if .datatype is set, then it is checked before calling this function
if not value or (#value == 0) then
return "" -- ignore on empty
elseif not DDNS.has_dnsserver then
elseif not has_dnsserver then
return nil, err_tab_adv(self) .. translate("Specifying a DNS-Server is not supported")
elseif not DTYP.host(value) then
return nil, err_tab_adv(self) .. translate("use hostname, FQDN, IPv4- or IPv6-Address")
@ -1179,13 +1197,16 @@ if DDNS.has_dnsserver or ( ( m:get(section, "dns_server") or "" ) ~= "" ) then
end
-- IPv4 + IPv6 - force_dnstcp -- ##############################################
if DDNS.has_bindhost or ( ( m:get(section, "force_dnstcp") or "0" ) ~= "0" ) then
local has_bindhost = DDNS.env_info("has_bindhost")
if has_bindhost or ( ( m:get(section, "force_dnstcp") or "0" ) ~= "0" ) then
tcp = ns:taboption("advanced", Flag, "force_dnstcp",
translate("Force TCP on DNS") )
tcp.orientation = "horizontal"
function tcp.cfgvalue(self, section)
local value = AbstractValue.cfgvalue(self, section)
if not DDNS.has_bindhost and value ~= "0" then
if not has_bindhost and value ~= "0" then
self.description = bold_on .. font_red ..
translate("DNS requests via TCP not supported") .. font_off .. "<br />" ..
translate("please disable") .. " !" .. bold_off
@ -1195,7 +1216,7 @@ if DDNS.has_bindhost or ( ( m:get(section, "force_dnstcp") or "0" ) ~= "0" ) the
return value
end
function tcp.validate(self, value)
if (value == "1" and DDNS.has_bindhost ) or value == "0" then
if (value == "1" and has_bindhost ) or value == "0" then
return value
end
return nil, err_tab_adv(self) .. translate("DNS requests via TCP not supported")
@ -1204,13 +1225,16 @@ end
-- IPv4 + IPv6 - proxy -- #####################################################
-- optional Proxy to use for http/https requests [user:password@]proxyhost[:port]
if DDNS.has_proxy or ( ( m:get(section, "proxy") or "" ) ~= "" ) then
local has_proxy = DDNS.env_info("has_proxy")
if has_proxy or ( ( m:get(section, "proxy") or "" ) ~= "" ) then
pxy = ns:taboption("advanced", Value, "proxy",
translate("PROXY-Server") )
pxy.placeholder="user:password@myproxy.lan:8080"
function pxy.cfgvalue(self, section)
local value = AbstractValue.cfgvalue(self, section)
if not DDNS.has_proxy and value ~= "" then
if not has_proxy and value ~= "" then
self.description = bold_on .. font_red ..
translate("PROXY-Server not supported") .. font_off .. "<br />" ..
translate("please remove entry") .. "!" .. bold_off
@ -1226,7 +1250,7 @@ if DDNS.has_proxy or ( ( m:get(section, "proxy") or "" ) ~= "" ) then
-- if .datatype is set, then it is checked before calling this function
if not value or (#value == 0) then
return "" -- ignore on empty
elseif DDNS.has_proxy then
elseif has_proxy then
local ipv6 = usev6:formvalue(section) or "0"
local force = fipv:formvalue(section) or "0"
local command = CTRL.luci_helper .. [[ -]]

View file

@ -48,7 +48,7 @@ if not SYS.init.enabled("ddns") then
end
-- No IPv6 support
if not DDNS.has_ipv6 then
if not DDNS.env_info("has_ipv6") then
local v6 = s:option(DummyValue, "_no_ipv6")
v6.titleref = 'http://www.openwrt.org" target="_blank'
v6.rawhtml = true
@ -60,7 +60,7 @@ if not DDNS.has_ipv6 then
end
-- No HTTPS support
if not DDNS.has_ssl then
if not DDNS.env_info("has_ssl") then
local sl = s:option(DummyValue, "_no_https")
sl.titleref = DISP.build_url("admin", "system", "packages")
sl.rawhtml = true
@ -74,7 +74,7 @@ if not DDNS.has_ssl then
end
-- No bind_network
if not DDNS.has_bindnet then
if not DDNS.env_info("has_bindnet") then
local bn = s:option(DummyValue, "_no_bind_network")
bn.titleref = DISP.build_url("admin", "system", "packages")
bn.rawhtml = true
@ -90,7 +90,7 @@ if not DDNS.has_bindnet then
end
-- currently only cURL possibly without proxy support
if not DDNS.has_proxy then
if not DDNS.env_info("has_proxy") then
local px = s:option(DummyValue, "_no_proxy")
px.titleref = DISP.build_url("admin", "system", "packages")
px.rawhtml = true
@ -104,7 +104,7 @@ if not DDNS.has_proxy then
end
-- "Force IP Version not supported"
if not DDNS.has_forceip then
if not DDNS.env_info("has_forceip") then
local fi = s:option(DummyValue, "_no_force_ip")
fi.titleref = DISP.build_url("admin", "system", "packages")
fi.rawhtml = true
@ -112,11 +112,11 @@ if not DDNS.has_forceip then
translate("Force IP Version not supported") .. bold_off
local value = translate("BusyBox's nslookup and Wget do not support to specify " ..
"the IP version to use for communication with DDNS Provider!")
if not (DDNS.has_wgetssl or DDNS.has_curl or DDNS.has_fetch) then
if not (DDNS.env_info("has_wgetssl") or DDNS.env_info("has_curl") or DDNS.env_info("has_fetch")) then
value = value .. "<br />- " ..
translate("You should install 'wget' or 'curl' or 'uclient-fetch' package.")
end
if not DDNS.has_bindhost then
if not DDNS.env_info("has_bindhost") then
value = value .. "<br />- " ..
translate("You should install 'bind-host' or 'knot-host' or 'drill' package for DNS requests.")
end
@ -124,7 +124,7 @@ if not DDNS.has_forceip then
end
-- "DNS requests via TCP not supported"
if not DDNS.has_bindhost then
if not DDNS.env_info("has_bindhost") then
local dt = s:option(DummyValue, "_no_dnstcp")
dt.titleref = DISP.build_url("admin", "system", "packages")
dt.rawhtml = true
@ -137,7 +137,7 @@ if not DDNS.has_bindhost then
end
-- nslookup compiled with musl produce problems when using
if not DDNS.has_dnsserver then
if not DDNS.env_info("has_dnsserver") then
local ds = s:option(DummyValue, "_no_dnsserver")
ds.titleref = DISP.build_url("admin", "system", "packages")
ds.rawhtml = true
@ -151,7 +151,7 @@ if not DDNS.has_dnsserver then
end
-- certificates installed
if DDNS.has_ssl and not DDNS.has_cacerts then
if DDNS.env_info("has_ssl") and not DDNS.env_info("has_cacerts") then
local ca = s:option(DummyValue, "_no_certs")
ca.titleref = DISP.build_url("admin", "system", "packages")
ca.rawhtml = true

View file

@ -1,21 +1,20 @@
-- Copyright 2014-2018 Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
-- Licensed to the public under the Apache License 2.0.
local NXFS = require "nixio.fs"
local DISP = require "luci.dispatcher"
local HTTP = require "luci.http"
local SYS = require "luci.sys"
local CTRL = require "luci.controller.ddns" -- this application's controller
local DDNS = require "luci.tools.ddns" -- ddns multiused functions
local show_hints = not (DDNS.has_ipv6 -- IPv6 support
and DDNS.has_ssl -- HTTPS support
and DDNS.has_proxy -- Proxy support
and DDNS.has_bindhost -- DNS TCP support
and DDNS.has_forceip -- Force IP version
and DDNS.has_dnsserver -- DNS server support
and DDNS.has_bindnet -- Bind to network/interface
and DDNS.has_cacerts -- certificates installed at /etc/ssl/certs
local show_hints = not (DDNS.env_info("has_ipv6") -- IPv6 support
and DDNS.env_info("has_ssl") -- HTTPS support
and DDNS.env_info("has_proxy") -- Proxy support
and DDNS.env_info("has_bindhost") -- DNS TCP support
and DDNS.env_info("has_forceip") -- Force IP version
and DDNS.env_info("has_dnsserver") -- DNS server support
and DDNS.env_info("has_bindnet") -- Bind to network/interface
and DDNS.env_info("has_cacerts") -- certificates installed at /etc/ssl/certs
)
local not_enabled = not SYS.init.enabled("ddns")
local need_update = not CTRL.service_ok()

View file

@ -5,37 +5,135 @@ module("luci.tools.ddns", package.seeall)
local NX = require "nixio"
local NXFS = require "nixio.fs"
local OPKG = require "luci.model.ipkg"
local UCI = require "luci.model.uci"
local SYS = require "luci.sys"
local UTIL = require "luci.util"
local function _check_certs()
local _, v = NXFS.glob("/etc/ssl/certs/*.crt")
if ( v == 0 ) then _, v = NXFS.glob("/etc/ssl/certs/*.pem") end
return (v > 0)
function env_info(type)
if ( type == "has_ssl" ) or ( type == "has_proxy" ) or ( type == "has_forceip" )
or ( type == "has_bindnet" ) or ( type == "has_fetch" )
or ( type == "has_wgetssl" ) or ( type == "has_curl" )
or ( type == "has_curlssl" ) or ( type == "has_curlpxy" )
or ( type == "has_fetchssl" ) or ( type == "has_bbwget" ) then
local function has_wgetssl()
return (SYS.call( [[which wget-ssl >/dev/null 2>&1]] ) == 0) -- and true or nil
end
local function has_curlssl()
return (SYS.call( [[$(which curl) -V 2>&1 | grep "Protocols:" | grep -qF "https"]] ) ~= 0)
end
local function has_fetch()
return (SYS.call( [[which uclient-fetch >/dev/null 2>&1]] ) == 0)
end
local function has_fetchssl()
return NXFS.access("/lib/libustream-ssl.so")
end
local function has_curl()
return (SYS.call( [[which curl >/dev/null 2>&1]] ) == 0)
end
local function has_curlpxy()
return (SYS.call( [[grep -i "all_proxy" /usr/lib/libcurl.so* >/dev/null 2>&1]] ) == 0)
end
local function has_bbwget()
return (SYS.call( [[$(which wget) -V 2>&1 | grep -iqF "busybox"]] ) == 0)
end
if type == "has_wgetssl" then
return has_wgetssl()
elseif type == "has_curl" then
return has_curl()
elseif type == "has_curlssl" then
return has_curlssl()
elseif type == "has_curlpxy" then
return has_curlpxy()
elseif type == "has_fetch" then
return has_fetch()
elseif type == "has_fetchssl" then
return has_fetchssl()
elseif type == "has_bbwget" then
return has_bbwget()
elseif type == "has_ssl" then
if has_wgetssl() then return true end
if has_curlssl() then return true end
if (has_fetch() and has_fetchssl()) then return true end
return false
elseif type == "has_proxy" then
if has_wgetssl() then return true end
if has_curlpxy() then return true end
if has_fetch() then return true end
if has_bbwget() then return true end
return false
elseif type == "has_forceip" then
if has_wgetssl() then return true end
if has_curl() then return true end
if has_fetch() then return true end -- only really needed for transfer
return false
elseif type == "has_bindnet" then
if has_curl() then return true end
if has_wgetssl() then return true end
return false
end
elseif ( type == "has_dnsserver" ) or ( type == "has_bindhost" ) or ( type == "has_hostip" ) or ( type == "has_nslookup" ) then
local function has_bindhost()
if (SYS.call( [[which host >/dev/null 2>&1]] ) == 0) then return true end
if (SYS.call( [[which host >/dev/null 2>&1]] ) == 0) then return true end
if (SYS.call( [[which khost >/dev/null 2>&1]] ) == 0) then return true end
if (SYS.call( [[which drill >/dev/null 2>&1]] ) == 0) then return true end
return false
end
local function has_hostip()
return (SYS.call( [[which hostip >/dev/null 2>&1]] ) == 0)
end
local function has_nslookup()
return (SYS.call( [[$(which nslookup) localhost 2>&1 | grep -qF "(null)"]] ) ~= 0)
end
if type == "has_bindhost" then
return has_bindhost()
elseif type == "has_hostip" then
return has_hostip()
elseif type == "has_nslookup" then
return has_nslookup()
elseif tyep == "has_dnsserver" then
if has_bindhost() then return true end
if has_hostip() then return true end
if has_nslookup() then return true end
return false
end
elseif type == "has_ipv6" then
return (NXFS.access("/proc/net/ipv6_route") and NXFS.access("/usr/sbin/ip6tables"))
elseif type == "has_cacerts" then
--old _check_certs() local function
local _, v = NXFS.glob("/etc/ssl/certs/*.crt")
if ( v == 0 ) then _, v = NXFS.glob("/etc/ssl/certs/*.pem") end
return (v > 0)
else
return
end
end
has_wgetssl = (SYS.call( [[which wget-ssl >/dev/null 2>&1]] ) == 0) -- and true or nil
has_curl = (SYS.call( [[which curl >/dev/null 2>&1]] ) == 0)
has_curlssl = (SYS.call( [[$(which curl) -V 2>&1 | grep "Protocols:" | grep -qF "https"]] ) ~= 0)
has_curlpxy = (SYS.call( [[grep -i "all_proxy" /usr/lib/libcurl.so* >/dev/null 2>&1]] ) == 0)
has_fetch = (SYS.call( [[which uclient-fetch >/dev/null 2>&1]] ) == 0)
has_fetchssl = NXFS.access("/lib/libustream-ssl.so")
has_bbwget = (SYS.call( [[$(which wget) -V 2>&1 | grep -iqF "busybox"]] ) == 0)
has_bindhost = (SYS.call( [[which host >/dev/null 2>&1]] ) == 0)
or (SYS.call( [[which khost >/dev/null 2>&1]] ) == 0)
or (SYS.call( [[which drill >/dev/null 2>&1]] ) == 0)
has_hostip = (SYS.call( [[which hostip >/dev/null 2>&1]] ) == 0)
has_nslookup = (SYS.call( [[$(which nslookup) localhost 2>&1 | grep -qF "(null)"]] ) ~= 0)
has_ipv6 = (NXFS.access("/proc/net/ipv6_route") and NXFS.access("/usr/sbin/ip6tables"))
has_ssl = (has_wgetssl or has_curlssl or (has_fetch and has_fetchssl))
has_proxy = (has_wgetssl or has_curlpxy or has_fetch or has_bbwget)
has_forceip = (has_wgetssl or has_curl or has_fetch) -- only really needed for transfer
has_dnsserver = (has_bindhost or has_hostip or has_nslookup)
has_bindnet = (has_wgetssl or has_curl)
has_cacerts = _check_certs()
-- function to calculate seconds from given interval and unit
function calc_seconds(interval, unit)
if not tonumber(interval) then

View file

@ -1,4 +1,3 @@
<!-- ++ BEGIN ++ Dynamic DNS ++ system_status.htm ++ -->
<script type="text/javascript">//<![CDATA[
// helper to move status data to the relevant
@ -10,8 +9,8 @@
if ( !(tbl) ) { return; }
// clear all rows
while (tbl.rows.length > 1)
tbl.deleteRow(1);
while (tbl.firstElementChild !== tbl.lastElementChild)
tbl.removeChild(tbl.lastElementChild);
// variable for Modulo-Division use to set cbi-rowstyle-? (0 or 1)
var i = -1;
@ -21,22 +20,22 @@
if (data[0].enabled == 0) {
var txt = '<strong><font color="red"><%:DDNS Autostart disabled%></font>' ;
var url = '<a href="' + data[0].url_up + '"><%:enable here%></a></strong>' ;
var tr = tbl.insertRow(-1);
tr.className = 'cbi-section-table-row cbi-rowstyle-' + (((j + i) % 2) + 1);
var td = tr.insertCell(-1);
td.colSpan = 2 ;
td.innerHTML = txt + " - " + url
tr.insertCell(-1).colSpan = 3 ;
tbl.appendChild(E('<div class="tr cbi-section-table-row cbi-rowstyle-%d">'.format(((j + i) % 2) + 1), [
E('<div class="td">', [ txt," - ", url ])
]));
i++ ;
}
var configuration;
var next_update;
var lookup;
var registered_ip;
var network;
for( j = 1; j < data.length; j++ )
{
var tr = tbl.insertRow(-1);
tr.className = 'cbi-section-table-row cbi-rowstyle-' + (((j + i) % 2) + 1) ;
// configuration
tr.insertCell(-1).innerHTML = '<strong>' + data[j].section + '</strong>' ;
configuration = data[j].section;
// pid
// data[j].pid ignored here
@ -47,66 +46,74 @@
// next update
switch (data[j].datenext) {
case "_empty_":
tr.insertCell(-1).innerHTML = '<em><%:Unknown error%></em>' ;
next_update = '<em><%:Unknown error%></em>';
break;
case "_stopped_":
tr.insertCell(-1).innerHTML = '<em><%:Stopped%></em>' ;
next_update = '<em><%:Stopped%></em>';
break;
case "_disabled_":
tr.insertCell(-1).innerHTML = '<em><%:Disabled%></em>' ;
next_update = '<em><%:Disabled%></em>';
break;
case "_noupdate_":
tr.insertCell(-1).innerHTML = '<em><%:Update error%></em>' ;
next_update = '<em><%:Update error%></em>';
break;
case "_runonce_":
tr.insertCell(-1).innerHTML = '<em><%:Run once%></em>' ;
next_update = '<em><%:Run once%></em>';
break;
case "_verify_":
tr.insertCell(-1).innerHTML = '<em><%:Verify%></em>';
next_update = '<em><%:Verify%></em>';
break;
default:
tr.insertCell(-1).innerHTML = data[j].datenext ;
next_update = data[j].datenext;
break;
}
// lookup
if (data[j].lookup == "_nolookup_")
tr.insertCell(-1).innerHTML = '<em><%:config error%></em>';
lookup = '<em><%:config error%></em>';
else
tr.insertCell(-1).innerHTML = data[j].lookup;
lookup = data[j].lookup;
// registered IP
switch (data[j].reg_ip) {
case "_nolookup_":
tr.insertCell(-1).innerHTML = '<em><%:Config error%></em>';
registered_ip = '<em><%:config error%></em>';
break;
case "_nodata_":
tr.insertCell(-1).innerHTML = '<em><%:No data%></em>';
registered_ip = '<em><%:No data%></em>';
break;
case "_noipv6_":
tr.insertCell(-1).innerHTML = '<em><%:IPv6 not supported%></em>';
registered_ip = '<em><%:IPv6 not supported%></em>';
break;
default:
tr.insertCell(-1).innerHTML = data[j].reg_ip;
registered_ip = data[j].reg_ip;
break;
}
// monitored interface
if (data[j].iface == "_nonet_")
tr.insertCell(-1).innerHTML = '<em><%:Config error%></em>';
network = '<em><%:Config error%></em>';
else
tr.insertCell(-1).innerHTML = data[j].iface;
network = data[j].iface;
tbl.appendChild(E('<div class="tr cbi-section-table-row cbi-rowstyle-%d">'.format(((j + i) % 2) + 1), [
E('<div class="td">', [ E('<strong>', configuration) ]),
E('<div class="td">', next_update),
E('<div class="td">', lookup),
E('<div class="td">', registered_ip),
E('<div class="td">', network)
]));
}
if (tbl.rows.length == 1 || (data[0].enabled == 0 && tbl.rows.length == 2) ) {
if (tbl.firstElementChild === tbl.lastElementChild || (data[0].enabled == 0 && tbl.childNodes.length == 2) ) {
var br = '<br />';
if (tbl.rows.length > 1)
var msg = '<%:There is no service configured.%>';
if (tbl.firstElementChild !== tbl.lastElementChild)
br = '';
var tr = tbl.insertRow(-1);
tr.className = "cbi-section-table-row";
var td = tr.insertCell(-1);
td.colSpan = 5;
td.innerHTML = '<em>' + br + '<%:There is no service configured.%></em>' ;
msg = br + msg;
tbl.appendChild(E('<div class="tr cbi-section-table-row">', [
E('<div class="td">', [ E('<em>', msg) ])
]));
}
}
@ -128,17 +135,17 @@
<fieldset class="cbi-section" id="ddns_status_section">
<legend><a href="<%=url([[admin]], [[services]], [[ddns]])%>"><%:Dynamic DNS%></a></legend>
<table class="cbi-section-table" id="ddns_status_table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Configuration%></th>
<th class="cbi-section-table-cell"><%:Next Update%></th>
<th class="cbi-section-table-cell"><%:Lookup Hostname%></th>
<th class="cbi-section-table-cell"><%:Registered IP%></th>
<th class="cbi-section-table-cell"><%:Network%></th>
</tr>
<tr class="cbi-section-table-row">
<td colspan="5"><em><br /><%:Collecting data...%></em></td>
</tr>
</table>
<div class="table cbi-section-table" id="ddns_status_table">
<div class="tr cbi-section-table-titles">
<div class="th cbi-section-table-cell"><%:Configuration%></div>
<div class="th cbi-section-table-cell"><%:Next Update%></div>
<div class="th cbi-section-table-cell"><%:Lookup Hostname%></div>
<div class="th cbi-section-table-cell"><%:Registered IP%></div>
<div class="th cbi-section-table-cell"><%:Network%></div>
</div>
<div class="tr cbi-section-table-row">
<div class="td"><em><br /><%:Collecting data...%></em></div>
</div>
</div>
</fieldset>
<!-- ++ END ++ Dynamic DNS ++ system_status.htm ++ -->

View file

@ -55,6 +55,7 @@ o = s:option(Value, "src", translate("Source zone"))
o.nocreate = true
o.default = "wan"
o.template = "cbi/firewall_zonelist"
o.rmempty = false
o = s:option(DynamicList, "src_mac",
@ -88,6 +89,10 @@ o.rmempty = true
o.datatype = "neg(portrange)"
o.placeholder = translate("any")
o:depends("proto", "tcp")
o:depends("proto", "udp")
o:depends("proto", "tcp udp")
o:depends("proto", "tcpudp")
o = s:option(Value, "src_dip",
translate("External IP address"),
@ -108,7 +113,10 @@ o = s:option(Value, "src_dport", translate("External port"),
"destination port or port range on this host"))
o.datatype = "neg(portrange)"
o:depends("proto", "tcp")
o:depends("proto", "udp")
o:depends("proto", "tcp udp")
o:depends("proto", "tcpudp")
o = s:option(Value, "dest", translate("Internal zone"))
o.nocreate = true
@ -133,6 +141,10 @@ o = s:option(Value, "dest_port",
o.placeholder = translate("any")
o.datatype = "portrange"
o:depends("proto", "tcp")
o:depends("proto", "udp")
o:depends("proto", "tcp udp")
o:depends("proto", "tcpudp")
o = s:option(Flag, "reflection", translate("Enable NAT Loopback"))
o.rmempty = true

View file

@ -54,7 +54,7 @@ function s.parse(self, ...)
if created then
m.uci:save("firewall")
luci.http.redirect(ds.build_url(
"admin/network/firewall/redirect", created
"admin/network/firewall/forwards", created
))
end
end
@ -63,8 +63,9 @@ function s.filter(self, sid)
return (self.map:get(sid, "target") ~= "SNAT")
end
ft.opt_name(s, DummyValue, translate("Name"))
function s.sectiontitle(self, sid)
return (self.map:get(sid, "name") or translate("Unnamed forward"))
end
local function forward_proto_txt(self, s)
@ -103,7 +104,6 @@ end
match = s:option(DummyValue, "match", translate("Match"))
match.rawhtml = true
match.width = "50%"
function match.cfgvalue(self, s)
return "<small>%s<br />%s<br />%s</small>" % {
forward_proto_txt(self, s),
@ -115,7 +115,6 @@ end
dest = s:option(DummyValue, "dest", translate("Forward to"))
dest.rawhtml = true
dest.width = "40%"
function dest.cfgvalue(self, s)
local z = ft.fmt_zone(self.map:get(s, "dest"), translate("any zone"))
local a = ft.fmt_ip(self.map:get(s, "dest_ip"), translate("any host"))
@ -129,6 +128,6 @@ function dest.cfgvalue(self, s)
end
end
ft.opt_enabled(s, Flag, translate("Enable")).width = "1%"
ft.opt_enabled(s, Flag, translate("Enable"))
return m

View file

@ -115,6 +115,10 @@ elseif rule_type == "redirect" then
o.datatype = "neg(portrange)"
o.placeholder = translate("any")
o:depends("proto", "tcp")
o:depends("proto", "udp")
o:depends("proto", "tcp udp")
o:depends("proto", "tcpudp")
o = s:option(Value, "dest", translate("Destination zone"))
o.nocreate = true
@ -139,6 +143,10 @@ elseif rule_type == "redirect" then
o.placeholder = translate("any")
o.datatype = "neg(portrange)"
o:depends("proto", "tcp")
o:depends("proto", "udp")
o:depends("proto", "tcp udp")
o:depends("proto", "tcpudp")
o = s:option(Value, "src_dip",
translate("SNAT IP address"),
@ -163,6 +171,10 @@ elseif rule_type == "redirect" then
o.rmempty = true
o.placeholder = translate('Do not rewrite')
o:depends("proto", "tcp")
o:depends("proto", "udp")
o:depends("proto", "tcp udp")
o:depends("proto", "tcpudp")
s:option(Value, "extra",
translate("Extra arguments"),
@ -212,7 +224,13 @@ else
end
o = s:option(DynamicList, "icmp_type", translate("Match ICMP type"))
o = s:option(DropDown, "icmp_type", translate("Match ICMP type"))
o.multiple = true
o.display = 10
o.dropdown = 10
o.custom = true
o.cast = "table"
o:value("", "any")
o:value("echo-reply")
o:value("destination-unreachable")
@ -251,11 +269,13 @@ else
o:value("address-mask-request")
o:value("address-mask-reply")
o:depends("proto", "icmp")
o = s:option(Value, "src", translate("Source zone"))
o.nocreate = true
o.allowany = true
o.default = "wan"
o.allowlocal = "src"
o.template = "cbi/firewall_zonelist"
@ -269,7 +289,7 @@ else
o = s:option(Value, "src_ip", translate("Source address"))
o.datatype = "neg(ipmask)"
o.datatype = "list(neg(ipmask))"
o.placeholder = translate("any")
luci.sys.net.ipv4_hints(function(ip, name)
@ -281,16 +301,29 @@ else
o.datatype = "list(neg(portrange))"
o.placeholder = translate("any")
o:depends("proto", "tcp")
o:depends("proto", "udp")
o:depends("proto", "tcp udp")
o:depends("proto", "tcpudp")
o = s:option(Value, "dest", translate("Destination zone"))
o = s:option(Value, "dest_local", translate("Output zone"))
o.nocreate = true
o.allowany = true
o.template = "cbi/firewall_zonelist"
o.alias = "dest"
o:depends("src", "")
o = s:option(Value, "dest_remote", translate("Destination zone"))
o.nocreate = true
o.allowany = true
o.allowlocal = true
o.template = "cbi/firewall_zonelist"
o.alias = "dest"
o:depends({["src"] = "", ["!reverse"] = true})
o = s:option(Value, "dest_ip", translate("Destination address"))
o.datatype = "neg(ipmask)"
o.datatype = "list(neg(ipmask))"
o.placeholder = translate("any")
luci.sys.net.ipv4_hints(function(ip, name)
@ -302,6 +335,10 @@ else
o.datatype = "list(neg(portrange))"
o.placeholder = translate("any")
o:depends("proto", "tcp")
o:depends("proto", "udp")
o:depends("proto", "tcp udp")
o:depends("proto", "tcpudp")
o = s:option(ListValue, "target", translate("Action"))
o.default = "ACCEPT"
@ -316,9 +353,9 @@ else
translate("Passes additional arguments to iptables. Use with care!"))
end
o = s:option(MultiValue, "weekdays", translate("Week Days"))
o.oneline = true
o.widget = "checkbox"
o = s:option(DropDown, "weekdays", translate("Week Days"))
o.multiple = true
o.display = 5
o:value("Sun", translate("Sunday"))
o:value("Mon", translate("Monday"))
o:value("Tue", translate("Tuesday"))
@ -327,9 +364,9 @@ o:value("Thu", translate("Thursday"))
o:value("Fri", translate("Friday"))
o:value("Sat", translate("Saturday"))
o = s:option(MultiValue, "monthdays", translate("Month Days"))
o.oneline = true
o.widget = "checkbox"
o = s:option(DropDown, "monthdays", translate("Month Days"))
o.multiple = true
o.display = 15
for i = 1,31 do
o:value(translate(i))
end

View file

@ -72,7 +72,9 @@ function s.parse(self, ...)
end
end
ft.opt_name(s, DummyValue, translate("Name"))
function s.sectiontitle(self, sid)
return (self.map:get(sid, "name") or translate("Unnamed rule"))
end
local function rule_proto_txt(self, s)
local f = self.map:get(s, "family")
@ -89,17 +91,31 @@ local function rule_proto_txt(self, s)
end
local function rule_src_txt(self, s)
local z = ft.fmt_zone(self.map:get(s, "src"), translate("any zone"))
local a = ft.fmt_ip(self.map:get(s, "src_ip"), translate("any host"))
local z = ft.fmt_zone(self.map:get(s, "src"))
local p = ft.fmt_port(self.map:get(s, "src_port"))
local m = ft.fmt_mac(self.map:get(s, "src_mac"))
if p and m then
return translatef("From %s in %s with source %s and %s", a, z, p, m)
elseif p or m then
return translatef("From %s in %s with source %s", a, z, p or m)
-- Forward/Input
if z and #z > 0 then
local a = ft.fmt_ip(self.map:get(s, "src_ip"), translate("any host"))
if p and m then
return translatef("From %s in %s with source %s and %s", a, z, p, m)
elseif p or m then
return translatef("From %s in %s with source %s", a, z, p or m)
else
return translatef("From %s in %s", a, z)
end
-- Output
else
return translatef("From %s in %s", a, z)
local a = ft.fmt_ip(self.map:get(s, "src_ip"), translate("any router IP"))
if p and m then
return translatef("From %s on <var>this device</var> with source %s and %s", a, p, m)
elseif p or m then
return translatef("From %s on <var>this device</var> with source %s", a, p or m)
else
return translatef("From %s on <var>this device</var>", a)
end
end
end
@ -145,7 +161,6 @@ end
match = s:option(DummyValue, "match", translate("Match"))
match.rawhtml = true
match.width = "70%"
function match.cfgvalue(self, s)
return "<small>%s<br />%s<br />%s</small>" % {
rule_proto_txt(self, s),
@ -156,9 +171,8 @@ end
target = s:option(DummyValue, "target", translate("Action"))
target.rawhtml = true
target.width = "20%"
function target.cfgvalue(self, s)
local t = ft.fmt_target(self.map:get(s, "target"), self.map:get(s, "dest"))
local t = ft.fmt_target(self.map:get(s, "target"), self.map:get(s, "src"), self.map:get(s, "dest"))
local l = ft.fmt_limit(self.map:get(s, "limit"),
self.map:get(s, "limit_burst"))
@ -169,7 +183,7 @@ function target.cfgvalue(self, s)
end
end
ft.opt_enabled(s, Flag, translate("Enable")).width = "1%"
ft.opt_enabled(s, Flag, translate("Enable"))
--
@ -226,11 +240,12 @@ function s.filter(self, sid)
return (self.map:get(sid, "target") == "SNAT")
end
ft.opt_name(s, DummyValue, translate("Name"))
function s.sectiontitle(self, sid)
return (self.map:get(sid, "name") or translate("Unnamed SNAT"))
end
match = s:option(DummyValue, "match", translate("Match"))
match.rawhtml = true
match.width = "70%"
function match.cfgvalue(self, s)
return "<small>%s<br />%s<br />%s</small>" % {
rule_proto_txt(self, s),
@ -241,7 +256,6 @@ end
snat = s:option(DummyValue, "via", translate("Action"))
snat.rawhtml = true
snat.width = "20%"
function snat.cfgvalue(self, s)
local a = ft.fmt_ip(self.map:get(s, "src_dip"))
local p = ft.fmt_port(self.map:get(s, "src_dport"))
@ -253,7 +267,7 @@ function snat.cfgvalue(self, s)
end
end
ft.opt_enabled(s, Flag, translate("Enable")).width = "1%"
ft.opt_enabled(s, Flag, translate("Enable"))
return m

View file

@ -101,9 +101,12 @@ end
function net.write(self, section, value)
zone:clear_networks()
local n
for n in ut.imatch(value) do
zone:add_network(n)
local net
for net in ut.imatch(value) do
local n = nw:get_network(net) or nw:add_network(net, { proto = "none" })
if n then
zone:add_network(n:name())
end
end
end

View file

@ -62,6 +62,11 @@ s.anonymous = true
s.addremove = true
s.extedit = ds.build_url("admin", "network", "firewall", "zones", "%s")
function s.sectiontitle(self, sid)
local z = fw:get_zone(sid)
return z:name()
end
function s.create(self)
local z = fw:new_zone()
if z then

View file

@ -198,8 +198,18 @@ function fmt_limit(limit, burst)
end
end
function fmt_target(x, dest)
if dest and #dest > 0 then
function fmt_target(x, src, dest)
if not src or #src == 0 then
if x == "ACCEPT" then
return _("Accept output")
elseif x == "REJECT" then
return _("Refuse output")
elseif x == "NOTRACK" then
return _("Do not track output")
else --if x == "DROP" then
return _("Discard output")
end
elseif dest and #dest > 0 then
if x == "ACCEPT" then
return _("Accept forward")
elseif x == "REJECT" then

View file

@ -18,95 +18,91 @@
vals[#vals+1] = '%s (%s)' %{ ip, name }
end)
-%>
<div class="cbi-section-create cbi-tblsection-create">
<br />
<table class="cbi-section-table" style="width:810px; margin-left:5px">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell" colspan="8"><%:New port forward%>:</th>
</tr>
<tr class="cbi-section-table-descr">
<th class="cbi-section-table-cell"><%:Name%></th>
<th class="cbi-section-table-cell"><%:Protocol%></th>
<th class="cbi-section-table-cell"><%:External zone%></th>
<th class="cbi-section-table-cell"><%:External port%></th>
<th class="cbi-section-table-cell"><%:Internal zone%></th>
<th class="cbi-section-table-cell"><%:Internal IP address%></th>
<th class="cbi-section-table-cell"><%:Internal port%></th>
<th class="cbi-section-table-cell"></th>
</tr>
<tr class="cbi-section-table-row">
<td class="cbi-section-table-cell">
<input type="text" class="cbi-input-text" id="_newfwd.name" name="_newfwd.name" placeholder="<%:New port forward%>" />
</td>
<td class="cbi-section-table-cell" style="width:110px">
<select class="cbi-input-select" id="_newfwd.proto" name="_newfwd.proto">
<option value="tcp udp">TCP+UDP</option>
<option value="tcp">TCP</option>
<option value="udp">UDP</option>
<option value="other"><%:Other...%></option>
</select>
</td>
<td class="cbi-section-table-cell" style="width:55px">
<select class="cbi-input-select" id="_newfwd.extzone" name="_newfwd.extzone">
<% for _, z in ipairs(ezl) do -%><option value="<%=z:name()%>"><%=z:name()%></option><%- end %>
</select>
</td>
<td class="cbi-section-table-cell" style="width:110px">
<input type="text" class="cbi-input-text" id="_newfwd.extport" name="_newfwd.extport" data-type="portrange" data-optional="true" />
</td>
<td class="cbi-section-table-cell" style="width:55px">
<select class="cbi-input-select" id="_newfwd.intzone" name="_newfwd.intzone">
<% for _, z in ipairs(izl) do -%><option value="<%=z:name()%>"><%=z:name()%></option><%- end %>
</select>
</td>
<td class="cbi-section-table-cell" style="width:110px">
<input type="text" class="cbi-input-text" id="_newfwd.intaddr" name="_newfwd.intaddr" data-type="host" data-optional="true"<%=
ifattr(#keys > 0, "data-choices", {keys, vals})
%>/>
</td>
<td class="cbi-section-table-cell" style="width:110px">
<input type="text" class="cbi-input-text" id="_newfwd.intport" name="_newfwd.intport" data-type="portrange" data-optional="true" />
</td>
<td class="cbi-section-table-cell">
<input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" value="<%:Add%>" />
</td>
</tr>
</table>
<script type="text/javascript">//<![CDATA[
cbi_bind(document.getElementById('_newfwd.extport'), 'blur',
function() {
var n = document.getElementById('_newfwd.name');
var p = document.getElementById('_newfwd.proto');
var i = document.getElementById('_newfwd.intport');
var hints = {
/* port name 0=both, 1=tcp, 2=udp, 3=other */
21: [ 'FTP', 1 ],
22: [ 'SSH', 1 ],
53: [ 'DNS', 0 ],
80: [ 'HTTP', 1 ],
443: [ 'HTTPS', 1 ],
3389: [ 'RDP', 1 ],
5900: [ 'VNC', 1 ],
};
if (!this.className.match(/invalid/))
{
if (!i.value) i.value = this.value;
var hint = hints[this.value || 0] || hints[i.value || 0];
if (hint)
{
p.selectedIndex = hint[1];
if (!n.value)
n.value = hint[0];
}
else if (!n.value)
{
n.value = 'Forward' + this.value;
}
}
});
//]]></script>
<h4><%:New port forward%></h4>
<div class="table">
<div class="tr table-titles">
<div class="th"><%:Name%></div>
<div class="th"><%:Protocol%></div>
<div class="th"><%:External zone%></div>
<div class="th"><%:External port%></div>
<div class="th"><%:Internal zone%></div>
<div class="th"><%:Internal IP address%></div>
<div class="th"><%:Internal port%></div>
<div class="th"></div>
</div>
<div class="tr">
<div class="td">
<input type="text" class="cbi-input-text" id="_newfwd.name" name="_newfwd.name" placeholder="<%:New port forward%>" />
</div>
<div class="td">
<select class="cbi-input-select" id="_newfwd.proto" name="_newfwd.proto">
<option value="tcp udp">TCP+UDP</option>
<option value="tcp">TCP</option>
<option value="udp">UDP</option>
<option value="other"><%:Other...%></option>
</select>
</div>
<div class="td">
<select class="cbi-input-select" id="_newfwd.extzone" name="_newfwd.extzone">
<% for _, z in ipairs(ezl) do -%><option value="<%=z:name()%>"><%=z:name()%></option><%- end %>
</select>
</div>
<div class="td">
<input type="text" class="cbi-input-text" id="_newfwd.extport" name="_newfwd.extport" data-type="portrange" data-optional="true" />
</div>
<div class="td">
<select class="cbi-input-select" id="_newfwd.intzone" name="_newfwd.intzone">
<% for _, z in ipairs(izl) do -%><option value="<%=z:name()%>"><%=z:name()%></option><%- end %>
</select>
</div>
<div class="td">
<input type="text" class="cbi-input-text" id="_newfwd.intaddr" name="_newfwd.intaddr" data-type="host" data-optional="true"<%=
ifattr(#keys > 0, "data-choices", {keys, vals})
%>/>
</div>
<div class="td">
<input type="text" class="cbi-input-text" id="_newfwd.intport" name="_newfwd.intport" data-type="portrange" data-optional="true" />
</div>
<div class="td bottom">
<input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" value="<%:Add%>" />
</div>
</div>
</div>
<script type="text/javascript">//<![CDATA[
cbi_bind(document.getElementById('_newfwd.extport'), 'blur',
function() {
var n = document.getElementById('_newfwd.name');
var p = document.getElementById('_newfwd.proto');
var i = document.getElementById('_newfwd.intport');
var hints = {
/* port name 0=both, 1=tcp, 2=udp, 3=other */
21: [ 'FTP', 1 ],
22: [ 'SSH', 1 ],
53: [ 'DNS', 0 ],
80: [ 'HTTP', 1 ],
443: [ 'HTTPS', 1 ],
3389: [ 'RDP', 1 ],
5900: [ 'VNC', 1 ],
};
if (!this.className.match(/invalid/))
{
if (!i.value) i.value = this.value;
var hint = hints[this.value || 0] || hints[i.value || 0];
if (hint)
{
p.selectedIndex = hint[1];
if (!n.value)
n.value = hint[0];
}
else if (!n.value)
{
n.value = 'Forward' + this.value;
}
}
});
//]]></script>

View file

@ -5,112 +5,105 @@
local zones = fw:get_zones()
%>
<div class="cbi-section-create cbi-tblsection-create">
<% if wz then %>
<br />
<table class="cbi-section-table" style="margin-left:5px">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell left" colspan="4"><%:Open ports on router%>:</th>
</tr>
<tr class="cbi-section-table-descr">
<th class="cbi-section-table-cell"><%:Name%></th>
<th class="cbi-section-table-cell"><%:Protocol%></th>
<th class="cbi-section-table-cell"><%:External port%></th>
<th class="cbi-section-table-cell"></th>
</tr>
<tr class="cbi-section-table-row">
<td class="cbi-section-table-cell" style="width:130px">
<input type="text" class="cbi-input-text" id="_newopen.name" name="_newopen.name" placeholder="<%:New input rule%>" />
</td>
<td class="cbi-section-table-cell" style="width:110px">
<select class="cbi-input-select" id="_newopen.proto" name="_newopen.proto">
<option value="tcp udp">TCP+UDP</option>
<option value="tcp">TCP</option>
<option value="udp">UDP</option>
<option value="other"><%:Other...%></option>
</select>
</td>
<td class="cbi-section-table-cell" style="width:110px">
<input type="text" class="cbi-input-text" id="_newopen.extport" name="_newopen.extport" />
</td>
<td class="cbi-section-table-cell left">
<input type="submit" class="cbi-button cbi-button-add" name="_newopen.submit" value="<%:Add%>" />
</td>
</tr>
</table>
<% end %>
<% if #zones > 1 then %>
<table class="cbi-section-table" style="margin-left:5px">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell left" colspan="6"><br /><%:New forward rule%>:</th>
</tr>
<tr class="cbi-section-table-descr">
<th class="cbi-section-table-cell"><%:Name%></th>
<th class="cbi-section-table-cell"><%:Source zone%></th>
<th class="cbi-section-table-cell"><%:Destination zone%></th>
<th class="cbi-section-table-cell"></th>
</tr>
<tr class="cbi-section-table-row">
<td class="cbi-section-table-cell" style="width:130px">
<input type="text" class="cbi-input-text" id="_newfwd.name" name="_newfwd.name" placeholder="<%:New forward rule%>" />
</td>
<td class="cbi-section-table-cell" style="width:110px">
<select class="cbi-input-text" id="_newfwd.src" name="_newfwd.src">
<% local k, v; for k, v in ipairs(fw:get_zones()) do -%>
<option<%=ifattr(v:name() == "wan", "selected", "selected")%> value="<%=v:name()%>"><%=v:name()%></option>
<%- end %>
</select>
</td>
<td class="cbi-section-table-cell" style="width:110px">
<select class="cbi-input-text" id="_newfwd.dest" name="_newfwd.dest">
<% local k, v; for k, v in ipairs(fw:get_zones()) do -%>
<option<%=ifattr(v:name() == "lan", "selected", "selected")%> value="<%=v:name()%>"><%=v:name()%></option>
<%- end %>
</select>
</td>
<td class="cbi-section-table-cell left">
<input type="submit" class="cbi-button cbi-button-link" name="_newfwd.submit" value="<%:Add and edit...%>" />
</td>
</tr>
</table>
<% else %>
<input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" value="<%:Add%>" />
<% end %>
<% if wz then %>
<h4><%:Open ports on router%></h4>
<div class="table">
<div class="tr cbi-section-table-titles">
<div class="th"><%:Name%></div>
<div class="th"><%:Protocol%></div>
<div class="th"><%:External port%></div>
<div class="th"></div>
</div>
<div class="tr">
<div class="td">
<input type="text" class="cbi-input-text" id="_newopen.name" name="_newopen.name" placeholder="<%:New input rule%>" />
</div>
<div class="td">
<select class="cbi-input-select" id="_newopen.proto" name="_newopen.proto">
<option value="tcp udp">TCP+UDP</option>
<option value="tcp">TCP</option>
<option value="udp">UDP</option>
<option value="other"><%:Other...%></option>
</select>
</div>
<div class="td">
<input type="text" class="cbi-input-text" id="_newopen.extport" name="_newopen.extport" />
</div>
<div class="td bottom">
<input type="submit" class="cbi-button cbi-button-add" name="_newopen.submit" value="<%:Add%>" />
</div>
</div>
</div>
<% end %>
<% if #zones > 1 then %>
<h4><%:New forward rule%></h4>
<div class="table">
<div class="tr cbi-section-table-titles">
<div class="th"><%:Name%></div>
<div class="th"><%:Source zone%></div>
<div class="th"><%:Destination zone%></div>
<div class="th"></div>
</div>
<div class="tr">
<div class="td">
<input type="text" class="cbi-input-text" id="_newfwd.name" name="_newfwd.name" placeholder="<%:New forward rule%>" />
</div>
<div class="td">
<select class="cbi-input-text" id="_newfwd.src" name="_newfwd.src">
<% local k, v; for k, v in ipairs(fw:get_zones()) do -%>
<option<%=ifattr(v:name() == "wan", "selected", "selected")%> value="<%=v:name()%>"><%=v:name()%></option>
<%- end %>
</select>
</div>
<div class="td">
<select class="cbi-input-text" id="_newfwd.dest" name="_newfwd.dest">
<% local k, v; for k, v in ipairs(fw:get_zones()) do -%>
<option<%=ifattr(v:name() == "lan", "selected", "selected")%> value="<%=v:name()%>"><%=v:name()%></option>
<%- end %>
</select>
</div>
<div class="td bottom">
<input type="submit" class="cbi-button cbi-button-link" name="_newfwd.submit" value="<%:Add and edit...%>" />
</div>
</div>
</div>
<% else %>
<input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" value="<%:Add%>" />
<% end %>
<% if wz then %>
<script type="text/javascript">//<![CDATA[
cbi_validate_field('_newopen.extport', true, 'list(neg(portrange))');
cbi_bind(document.getElementById('_newopen.extport'), 'blur',
function() {
var n = document.getElementById('_newopen.name');
var p = document.getElementById('_newopen.proto');
var hints = {
/* port name 0=both, 1=tcp, 2=udp, 3=other */
22: [ 'SSH', 1 ],
53: [ 'DNS', 0 ],
80: [ 'HTTP', 1 ],
443: [ 'HTTPS', 1 ],
};
<% if wz then %>
<script type="text/javascript">//<![CDATA[
cbi_validate_field('_newopen.extport', true, 'list(neg(portrange))');
cbi_bind(document.getElementById('_newopen.extport'), 'blur',
function() {
var n = document.getElementById('_newopen.name');
var p = document.getElementById('_newopen.proto');
var hints = {
/* port name 0=both, 1=tcp, 2=udp, 3=other */
22: [ 'SSH', 1 ],
53: [ 'DNS', 0 ],
80: [ 'HTTP', 1 ],
443: [ 'HTTPS', 1 ],
};
if (!this.className.match(/invalid/))
if (!this.className.match(/invalid/))
{
var hint = hints[this.value || 0];
if (hint)
{
var hint = hints[this.value || 0];
if (hint)
{
p.selectedIndex = hint[1];
p.selectedIndex = hint[1];
if (!n.value)
n.value = hint[0];
}
else if (!n.value && this.value)
{
n.value = 'Open' + this.value;
}
if (!n.value)
n.value = hint[0];
}
});
else if (!n.value && this.value)
{
n.value = 'Open' + this.value;
}
}
});
cbi_validate_field('cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>', true, 'uciname');
//]]></script>
<% end %>
</div>
cbi_validate_field('cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>', true, 'uciname');
//]]></script>
<% end %>

View file

@ -12,53 +12,48 @@
end
%>
<div class="cbi-section-create cbi-tblsection-create">
<% if #zones > 1 then %>
<br />
<table class="cbi-section-table" style="width:700px; margin-left:5px">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell left" colspan="6"><%:New source NAT%>:</th>
</tr>
<tr class="cbi-section-table-descr">
<th class="cbi-section-table-cell"><%:Name%></th>
<th class="cbi-section-table-cell"><%:Source zone%></th>
<th class="cbi-section-table-cell"><%:Destination zone%></th>
<th class="cbi-section-table-cell"><%:To source IP%></th>
<th class="cbi-section-table-cell"><%:To source port%></th>
<th class="cbi-section-table-cell"></th>
</tr>
<tr class="cbi-section-table-row">
<td class="cbi-section-table-cell">
<input type="text" class="cbi-input-text" id="_newsnat.name" name="_newsnat.name" placeholder="<%:New SNAT rule%>" />
</td>
<td class="cbi-section-table-cell" style="width:110px">
<select class="cbi-input-text" id="_newsnat.src" name="_newsnat.src">
<% local k, v; for k, v in ipairs(fw:get_zones()) do -%>
<option<%=ifattr(v:name() == "lan", "selected", "selected")%> value="<%=v:name()%>"><%=v:name()%></option>
<%- end %>
</select>
</td>
<td class="cbi-section-table-cell" style="width:110px">
<select class="cbi-input-text" id="_newsnat.dest" name="_newsnat.dest">
<% local k, v; for k, v in ipairs(fw:get_zones()) do -%>
<option<%=ifattr(v:name() == "wan", "selected", "selected")%> value="<%=v:name()%>"><%=v:name()%></option>
<%- end %>
</select>
</td>
<td class="cbi-section-table-cell" style="width:110px">
<input type="text" class="cbi-input-text" id="_newsnat.dip" name="_newsnat.dip" placeholder="<%:Do not rewrite%>" data-type="ip4addr" data-optional="true"<%=
ifattr(#keys > 0, "data-choices", { keys, vals })
%> />
</td>
<td class="cbi-section-table-cell" style="width:110px">
<input type="text" class="cbi-input-text" id="_newsnat.dport" name="_newsnat.dport" placeholder="<%:Do not rewrite%>" data-type="portrange" data-optional="true" />
</td>
<td class="cbi-section-table-cell">
<input type="submit" class="cbi-button cbi-button-link" name="_newsnat.submit" value="<%:Add and edit...%>" />
</td>
</tr>
</table>
<% else %>
<input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" value="<%:Add%>" />
<% end %>
</div>
<% if #zones > 1 then %>
<h4><%:New source NAT%></h4>
<div class="table">
<div class="tr cbi-section-table-titles">
<div class="th"><%:Name%></div>
<div class="th"><%:Source zone%></div>
<div class="th"><%:Destination zone%></div>
<div class="th"><%:To source IP%></div>
<div class="th"><%:To source port%></div>
<div class="th"></div>
</div>
<div class="tr">
<div class="td">
<input type="text" class="cbi-input-text" id="_newsnat.name" name="_newsnat.name" placeholder="<%:New SNAT rule%>" />
</div>
<div class="td">
<select class="cbi-input-text" id="_newsnat.src" name="_newsnat.src">
<% local k, v; for k, v in ipairs(fw:get_zones()) do -%>
<option<%=ifattr(v:name() == "lan", "selected", "selected")%> value="<%=v:name()%>"><%=v:name()%></option>
<%- end %>
</select>
</div>
<div class="td">
<select class="cbi-input-text" id="_newsnat.dest" name="_newsnat.dest">
<% local k, v; for k, v in ipairs(fw:get_zones()) do -%>
<option<%=ifattr(v:name() == "wan", "selected", "selected")%> value="<%=v:name()%>"><%=v:name()%></option>
<%- end %>
</select>
</div>
<div class="td">
<input type="text" class="cbi-input-text" id="_newsnat.dip" name="_newsnat.dip" placeholder="<%:Do not rewrite%>" data-type="ip4addr" data-optional="true"<%=
ifattr(#keys > 0, "data-choices", { keys, vals })
%> />
</div>
<div class="td">
<input type="text" class="cbi-input-text" id="_newsnat.dport" name="_newsnat.dport" placeholder="<%:Do not rewrite%>" data-type="portrange" data-optional="true" />
</div>
<div class="td bottom">
<input type="submit" class="cbi-button cbi-button-link" name="_newsnat.submit" value="<%:Add and edit...%>" />
</div>
</div>
</div>
<% else %>
<input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" value="<%:Add%>" />
<% end %>

View file

@ -48,6 +48,9 @@ msgstr ""
msgid "Accept input"
msgstr ""
msgid "Accept output"
msgstr ""
msgid "Action"
msgstr "Acció"
@ -106,6 +109,9 @@ msgstr ""
msgid "Discard input"
msgstr ""
msgid "Discard output"
msgstr ""
msgid "Do not rewrite"
msgstr "No reescriguis"
@ -115,6 +121,9 @@ msgstr ""
msgid "Do not track input"
msgstr ""
msgid "Do not track output"
msgstr ""
msgid "Drop invalid packets"
msgstr "Descarta els paquets invàlids"
@ -181,6 +190,15 @@ msgstr "Des de %s en %s amb origen %s"
msgid "From %s in %s with source %s and %s"
msgstr "Des de %s en %s amb orígens %s i %s"
msgid "From %s on <var>this device</var>"
msgstr ""
msgid "From %s on <var>this device</var> with source %s"
msgstr ""
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr ""
msgid "General Settings"
msgstr "Ajusts generals"
@ -314,6 +332,9 @@ msgstr "Altre..."
msgid "Output"
msgstr "Sortida"
msgid "Output zone"
msgstr ""
msgid "Passes additional arguments to iptables. Use with care!"
msgstr "Passa paràmetres addicionals al iptables. Utilitzeu-ho amb cura!"
@ -531,6 +552,15 @@ msgstr ""
msgid "Tuesday"
msgstr ""
msgid "Unnamed SNAT"
msgstr ""
msgid "Unnamed forward"
msgstr ""
msgid "Unnamed rule"
msgstr ""
msgid "Via %s"
msgstr "Via %s"

View file

@ -44,6 +44,9 @@ msgstr ""
msgid "Accept input"
msgstr ""
msgid "Accept output"
msgstr ""
msgid "Action"
msgstr "Akce"
@ -101,6 +104,9 @@ msgstr ""
msgid "Discard input"
msgstr ""
msgid "Discard output"
msgstr ""
msgid "Do not rewrite"
msgstr "Nepřepisovat"
@ -110,6 +116,9 @@ msgstr ""
msgid "Do not track input"
msgstr ""
msgid "Do not track output"
msgstr ""
msgid "Drop invalid packets"
msgstr "Zahazovat neplatné pakety"
@ -176,6 +185,15 @@ msgstr "Z %s v %s se zdrojovou %s"
msgid "From %s in %s with source %s and %s"
msgstr "Z %s v %s se zdrojovou %s a %s"
msgid "From %s on <var>this device</var>"
msgstr ""
msgid "From %s on <var>this device</var> with source %s"
msgstr ""
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr ""
msgid "General Settings"
msgstr "Obecné nastavení"
@ -309,6 +327,9 @@ msgstr "Ostatní ..."
msgid "Output"
msgstr "Výstup"
msgid "Output zone"
msgstr ""
msgid "Passes additional arguments to iptables. Use with care!"
msgstr "Předává další argumenty iptables. Používat opatrně!"
@ -526,6 +547,15 @@ msgstr ""
msgid "Tuesday"
msgstr ""
msgid "Unnamed SNAT"
msgstr ""
msgid "Unnamed forward"
msgstr ""
msgid "Unnamed rule"
msgstr ""
msgid "Via %s"
msgstr "Prostřednictvím %s"

View file

@ -46,6 +46,9 @@ msgstr ""
msgid "Accept input"
msgstr ""
msgid "Accept output"
msgstr ""
msgid "Action"
msgstr "Aktion"
@ -104,6 +107,9 @@ msgstr ""
msgid "Discard input"
msgstr ""
msgid "Discard output"
msgstr ""
msgid "Do not rewrite"
msgstr "Nicht umschreiben"
@ -113,6 +119,9 @@ msgstr ""
msgid "Do not track input"
msgstr ""
msgid "Do not track output"
msgstr ""
msgid "Drop invalid packets"
msgstr "Ungültige Pakete verwerfen"
@ -179,6 +188,15 @@ msgstr "Von %s in %s mit Quell-%s"
msgid "From %s in %s with source %s and %s"
msgstr "Von %s in %s mit Quell-%s und %s"
msgid "From %s on <var>this device</var>"
msgstr ""
msgid "From %s on <var>this device</var> with source %s"
msgstr ""
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr ""
msgid "General Settings"
msgstr "Allgemein"
@ -307,6 +325,9 @@ msgstr "Anderes..."
msgid "Output"
msgstr "Ausgang"
msgid "Output zone"
msgstr ""
msgid "Passes additional arguments to iptables. Use with care!"
msgstr ""
"Gibt zusätzliche Kommandozeilenargumente an iptables weiter. Mit Vorsicht "
@ -530,6 +551,15 @@ msgstr ""
msgid "Tuesday"
msgstr ""
msgid "Unnamed SNAT"
msgstr ""
msgid "Unnamed forward"
msgstr ""
msgid "Unnamed rule"
msgstr ""
msgid "Via %s"
msgstr "Über %s"

View file

@ -46,6 +46,9 @@ msgstr ""
msgid "Accept input"
msgstr ""
msgid "Accept output"
msgstr ""
msgid "Action"
msgstr "Ενέργεια"
@ -101,6 +104,9 @@ msgstr ""
msgid "Discard input"
msgstr ""
msgid "Discard output"
msgstr ""
msgid "Do not rewrite"
msgstr ""
@ -110,6 +116,9 @@ msgstr ""
msgid "Do not track input"
msgstr ""
msgid "Do not track output"
msgstr ""
msgid "Drop invalid packets"
msgstr "Αγνόηση μη-έγκυρων πακετών"
@ -177,6 +186,15 @@ msgstr ""
msgid "From %s in %s with source %s and %s"
msgstr ""
msgid "From %s on <var>this device</var>"
msgstr ""
msgid "From %s on <var>this device</var> with source %s"
msgstr ""
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr ""
msgid "General Settings"
msgstr "Γενικές Ρυθμίσεις"
@ -306,6 +324,9 @@ msgstr "Άλλο..."
msgid "Output"
msgstr "Έξοδος"
msgid "Output zone"
msgstr ""
msgid "Passes additional arguments to iptables. Use with care!"
msgstr ""
@ -498,6 +519,15 @@ msgstr ""
msgid "Tuesday"
msgstr ""
msgid "Unnamed SNAT"
msgstr ""
msgid "Unnamed forward"
msgstr ""
msgid "Unnamed rule"
msgstr ""
msgid "Via %s"
msgstr ""

View file

@ -44,6 +44,9 @@ msgstr ""
msgid "Accept input"
msgstr ""
msgid "Accept output"
msgstr ""
msgid "Action"
msgstr "Action"
@ -98,6 +101,9 @@ msgstr ""
msgid "Discard input"
msgstr ""
msgid "Discard output"
msgstr ""
msgid "Do not rewrite"
msgstr ""
@ -107,6 +113,9 @@ msgstr ""
msgid "Do not track input"
msgstr ""
msgid "Do not track output"
msgstr ""
msgid "Drop invalid packets"
msgstr "Drop invalid packets"
@ -177,6 +186,15 @@ msgstr ""
msgid "From %s in %s with source %s and %s"
msgstr ""
msgid "From %s on <var>this device</var>"
msgstr ""
msgid "From %s on <var>this device</var> with source %s"
msgstr ""
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr ""
msgid "General Settings"
msgstr ""
@ -305,6 +323,9 @@ msgstr ""
msgid "Output"
msgstr "Output"
msgid "Output zone"
msgstr ""
msgid "Passes additional arguments to iptables. Use with care!"
msgstr ""
@ -525,6 +546,15 @@ msgstr ""
msgid "Tuesday"
msgstr ""
msgid "Unnamed SNAT"
msgstr ""
msgid "Unnamed forward"
msgstr ""
msgid "Unnamed rule"
msgstr ""
msgid "Via %s"
msgstr ""

View file

@ -47,6 +47,9 @@ msgstr ""
msgid "Accept input"
msgstr ""
msgid "Accept output"
msgstr ""
msgid "Action"
msgstr "Acción"
@ -105,6 +108,9 @@ msgstr ""
msgid "Discard input"
msgstr ""
msgid "Discard output"
msgstr ""
msgid "Do not rewrite"
msgstr "No reescribir"
@ -114,6 +120,9 @@ msgstr ""
msgid "Do not track input"
msgstr ""
msgid "Do not track output"
msgstr ""
msgid "Drop invalid packets"
msgstr "Descartar paquetes no válidos"
@ -180,6 +189,15 @@ msgstr "Desde %s en %s con origen %s"
msgid "From %s in %s with source %s and %s"
msgstr "Desde %s en %s con origen %s y %s"
msgid "From %s on <var>this device</var>"
msgstr ""
msgid "From %s on <var>this device</var> with source %s"
msgstr ""
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr ""
msgid "General Settings"
msgstr "Configuración general"
@ -312,6 +330,9 @@ msgstr "Otros..."
msgid "Output"
msgstr "Salida"
msgid "Output zone"
msgstr ""
msgid "Passes additional arguments to iptables. Use with care!"
msgstr "Pasa más parámetros a IPTables. ¡Usar con cuidado!"
@ -529,6 +550,15 @@ msgstr ""
msgid "Tuesday"
msgstr ""
msgid "Unnamed SNAT"
msgstr ""
msgid "Unnamed forward"
msgstr ""
msgid "Unnamed rule"
msgstr ""
msgid "Via %s"
msgstr "Vía %s"

View file

@ -46,6 +46,9 @@ msgstr ""
msgid "Accept input"
msgstr ""
msgid "Accept output"
msgstr ""
msgid "Action"
msgstr "Action"
@ -100,6 +103,9 @@ msgstr ""
msgid "Discard input"
msgstr ""
msgid "Discard output"
msgstr ""
msgid "Do not rewrite"
msgstr ""
@ -109,6 +115,9 @@ msgstr ""
msgid "Do not track input"
msgstr ""
msgid "Do not track output"
msgstr ""
msgid "Drop invalid packets"
msgstr "Supprimer les paquets invalides"
@ -179,6 +188,15 @@ msgstr ""
msgid "From %s in %s with source %s and %s"
msgstr ""
msgid "From %s on <var>this device</var>"
msgstr ""
msgid "From %s on <var>this device</var> with source %s"
msgstr ""
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr ""
msgid "General Settings"
msgstr "Paramètres généraux"
@ -307,6 +325,9 @@ msgstr "Autre..."
msgid "Output"
msgstr "Sortie"
msgid "Output zone"
msgstr ""
msgid "Passes additional arguments to iptables. Use with care!"
msgstr ""
@ -551,6 +572,15 @@ msgstr ""
msgid "Tuesday"
msgstr ""
msgid "Unnamed SNAT"
msgstr ""
msgid "Unnamed forward"
msgstr ""
msgid "Unnamed rule"
msgstr ""
msgid "Via %s"
msgstr ""

View file

@ -41,6 +41,9 @@ msgstr ""
msgid "Accept input"
msgstr ""
msgid "Accept output"
msgstr ""
msgid "Action"
msgstr ""
@ -95,6 +98,9 @@ msgstr ""
msgid "Discard input"
msgstr ""
msgid "Discard output"
msgstr ""
msgid "Do not rewrite"
msgstr ""
@ -104,6 +110,9 @@ msgstr ""
msgid "Do not track input"
msgstr ""
msgid "Do not track output"
msgstr ""
msgid "Drop invalid packets"
msgstr ""
@ -170,6 +179,15 @@ msgstr ""
msgid "From %s in %s with source %s and %s"
msgstr ""
msgid "From %s on <var>this device</var>"
msgstr ""
msgid "From %s on <var>this device</var> with source %s"
msgstr ""
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr ""
msgid "General Settings"
msgstr ""
@ -296,6 +314,9 @@ msgstr ""
msgid "Output"
msgstr ""
msgid "Output zone"
msgstr ""
msgid "Passes additional arguments to iptables. Use with care!"
msgstr ""
@ -483,6 +504,15 @@ msgstr ""
msgid "Tuesday"
msgstr ""
msgid "Unnamed SNAT"
msgstr ""
msgid "Unnamed forward"
msgstr ""
msgid "Unnamed rule"
msgstr ""
msgid "Via %s"
msgstr ""

View file

@ -44,6 +44,9 @@ msgstr ""
msgid "Accept input"
msgstr ""
msgid "Accept output"
msgstr ""
msgid "Action"
msgstr "Művelet"
@ -102,6 +105,9 @@ msgstr ""
msgid "Discard input"
msgstr ""
msgid "Discard output"
msgstr ""
msgid "Do not rewrite"
msgstr "Ne írja felül"
@ -111,6 +117,9 @@ msgstr ""
msgid "Do not track input"
msgstr ""
msgid "Do not track output"
msgstr ""
msgid "Drop invalid packets"
msgstr "Érvénytelen csomagok eldobása"
@ -177,6 +186,15 @@ msgstr "%s felől %s-ben %s forrással"
msgid "From %s in %s with source %s and %s"
msgstr "%s felől %s-ben %s és %s forrással"
msgid "From %s on <var>this device</var>"
msgstr ""
msgid "From %s on <var>this device</var> with source %s"
msgstr ""
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr ""
msgid "General Settings"
msgstr "Általános beállítások"
@ -313,6 +331,9 @@ msgstr "Egyéb..."
msgid "Output"
msgstr "Kimenet"
msgid "Output zone"
msgstr ""
msgid "Passes additional arguments to iptables. Use with care!"
msgstr ""
"További argumentumok küldése az iptables részére. Használja körültekintően!"
@ -533,6 +554,15 @@ msgstr ""
msgid "Tuesday"
msgstr ""
msgid "Unnamed SNAT"
msgstr ""
msgid "Unnamed forward"
msgstr ""
msgid "Unnamed rule"
msgstr ""
msgid "Via %s"
msgstr "%s-en át"

View file

@ -46,6 +46,9 @@ msgstr ""
msgid "Accept input"
msgstr ""
msgid "Accept output"
msgstr ""
msgid "Action"
msgstr "Azione"
@ -104,6 +107,9 @@ msgstr ""
msgid "Discard input"
msgstr ""
msgid "Discard output"
msgstr ""
msgid "Do not rewrite"
msgstr "Non riscrivere"
@ -113,6 +119,9 @@ msgstr ""
msgid "Do not track input"
msgstr ""
msgid "Do not track output"
msgstr ""
msgid "Drop invalid packets"
msgstr "Scarta pacchetti invalidi"
@ -179,6 +188,15 @@ msgstr "Da %s a %s con sorgente %s"
msgid "From %s in %s with source %s and %s"
msgstr "Da %s a %s con sorgente %s e %s"
msgid "From %s on <var>this device</var>"
msgstr ""
msgid "From %s on <var>this device</var> with source %s"
msgstr ""
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr ""
msgid "General Settings"
msgstr "Opzioni Generali"
@ -311,6 +329,9 @@ msgstr "Altri..."
msgid "Output"
msgstr ""
msgid "Output zone"
msgstr ""
msgid "Passes additional arguments to iptables. Use with care!"
msgstr "Passa comandi addizionali a iptables. Usare con cura!"
@ -549,6 +570,15 @@ msgstr ""
msgid "Tuesday"
msgstr "Martedì"
msgid "Unnamed SNAT"
msgstr ""
msgid "Unnamed forward"
msgstr ""
msgid "Unnamed rule"
msgstr ""
msgid "Via %s"
msgstr ""

View file

@ -47,6 +47,9 @@ msgstr "転送を許可"
msgid "Accept input"
msgstr "入力を許可"
msgid "Accept output"
msgstr "出力を許可"
msgid "Action"
msgstr "動作"
@ -105,6 +108,9 @@ msgstr "転送を破棄"
msgid "Discard input"
msgstr "入力を破棄"
msgid "Discard output"
msgstr "出力を破棄"
msgid "Do not rewrite"
msgstr "リライトしない"
@ -114,6 +120,9 @@ msgstr "転送を追跡しない"
msgid "Do not track input"
msgstr "入力を追跡しない"
msgid "Do not track output"
msgstr "出力を追跡しない"
msgid "Drop invalid packets"
msgstr "無効なパケットを遮断する"
@ -175,10 +184,19 @@ msgid "From %s in %s"
msgstr "送信元 %s (%s)"
msgid "From %s in %s with source %s"
msgstr "送信元 %s (%s) , 送信元 %s"
msgstr "送信元 %s (%s) , %s"
msgid "From %s in %s with source %s and %s"
msgstr "送信元 %s (%s) , 送信元 %s, 送信元 %s"
msgstr "送信元 %s (%s) , %s, %s"
msgid "From %s on <var>this device</var>"
msgstr "送信元 %s (<var>デバイス</var>)"
msgid "From %s on <var>this device</var> with source %s"
msgstr "送信元 %s, %s (<var>デバイス</var>)"
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr "送信元 %s, %s, %s (<var>デバイス</var>)"
msgid "General Settings"
msgstr "一般設定"
@ -316,6 +334,9 @@ msgstr "その他のプロトコル"
msgid "Output"
msgstr "送信"
msgid "Output zone"
msgstr "出力ゾーン"
msgid "Passes additional arguments to iptables. Use with care!"
msgstr ""
"iptablesにパススルーする追加の引数を設定してください。ただし、注意して設定し"
@ -566,6 +587,15 @@ msgstr ""
msgid "Tuesday"
msgstr "火曜日"
msgid "Unnamed SNAT"
msgstr "名称未設定の SNAT"
msgid "Unnamed forward"
msgstr "名称未設定の転送"
msgid "Unnamed rule"
msgstr "名称未設定のルール"
msgid "Via %s"
msgstr "経由 %s"

View file

@ -46,6 +46,9 @@ msgstr ""
msgid "Accept input"
msgstr ""
msgid "Accept output"
msgstr ""
msgid "Action"
msgstr ""
@ -103,6 +106,9 @@ msgstr ""
msgid "Discard input"
msgstr ""
msgid "Discard output"
msgstr ""
msgid "Do not rewrite"
msgstr ""
@ -112,6 +118,9 @@ msgstr ""
msgid "Do not track input"
msgstr ""
msgid "Do not track output"
msgstr ""
msgid "Drop invalid packets"
msgstr ""
@ -178,6 +187,15 @@ msgstr ""
msgid "From %s in %s with source %s and %s"
msgstr ""
msgid "From %s on <var>this device</var>"
msgstr ""
msgid "From %s on <var>this device</var> with source %s"
msgstr ""
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr ""
msgid "General Settings"
msgstr ""
@ -304,6 +322,9 @@ msgstr ""
msgid "Output"
msgstr ""
msgid "Output zone"
msgstr ""
msgid "Passes additional arguments to iptables. Use with care!"
msgstr "iptables 명령에 추가 인자들을 더합니다. 조심해 사용하세요!"
@ -517,6 +538,15 @@ msgstr ""
msgid "Tuesday"
msgstr "화요일"
msgid "Unnamed SNAT"
msgstr ""
msgid "Unnamed forward"
msgstr ""
msgid "Unnamed rule"
msgstr ""
msgid "Via %s"
msgstr ""

View file

@ -40,6 +40,9 @@ msgstr ""
msgid "Accept input"
msgstr ""
msgid "Accept output"
msgstr ""
msgid "Action"
msgstr ""
@ -94,6 +97,9 @@ msgstr ""
msgid "Discard input"
msgstr ""
msgid "Discard output"
msgstr ""
msgid "Do not rewrite"
msgstr ""
@ -103,6 +109,9 @@ msgstr ""
msgid "Do not track input"
msgstr ""
msgid "Do not track output"
msgstr ""
msgid "Drop invalid packets"
msgstr ""
@ -169,6 +178,15 @@ msgstr ""
msgid "From %s in %s with source %s and %s"
msgstr ""
msgid "From %s on <var>this device</var>"
msgstr ""
msgid "From %s on <var>this device</var> with source %s"
msgstr ""
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr ""
msgid "General Settings"
msgstr ""
@ -295,6 +313,9 @@ msgstr ""
msgid "Output"
msgstr ""
msgid "Output zone"
msgstr ""
msgid "Passes additional arguments to iptables. Use with care!"
msgstr ""
@ -482,6 +503,15 @@ msgstr ""
msgid "Tuesday"
msgstr ""
msgid "Unnamed SNAT"
msgstr ""
msgid "Unnamed forward"
msgstr ""
msgid "Unnamed rule"
msgstr ""
msgid "Via %s"
msgstr ""

View file

@ -41,6 +41,9 @@ msgstr ""
msgid "Accept input"
msgstr ""
msgid "Accept output"
msgstr ""
msgid "Action"
msgstr "Handling"
@ -98,6 +101,9 @@ msgstr ""
msgid "Discard input"
msgstr ""
msgid "Discard output"
msgstr ""
msgid "Do not rewrite"
msgstr "Ikke omskriv"
@ -107,6 +113,9 @@ msgstr ""
msgid "Do not track input"
msgstr ""
msgid "Do not track output"
msgstr ""
msgid "Drop invalid packets"
msgstr "Forkast ugyldige pakker"
@ -174,6 +183,15 @@ msgstr "Fra %s i %s med kilde %s"
msgid "From %s in %s with source %s and %s"
msgstr "Fra %s i %s med kilde %s og %s"
msgid "From %s on <var>this device</var>"
msgstr ""
msgid "From %s on <var>this device</var> with source %s"
msgstr ""
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr ""
msgid "General Settings"
msgstr "Generelle Innstillinger"
@ -308,6 +326,9 @@ msgstr "Andre..."
msgid "Output"
msgstr "Utdata"
msgid "Output zone"
msgstr ""
msgid "Passes additional arguments to iptables. Use with care!"
msgstr "Sender flere argumenter til iptables. Bruk med forsiktighet!"
@ -527,6 +548,15 @@ msgstr ""
msgid "Tuesday"
msgstr ""
msgid "Unnamed SNAT"
msgstr ""
msgid "Unnamed forward"
msgstr ""
msgid "Unnamed rule"
msgstr ""
msgid "Via %s"
msgstr "Via %s"

View file

@ -48,6 +48,9 @@ msgstr ""
msgid "Accept input"
msgstr ""
msgid "Accept output"
msgstr ""
msgid "Action"
msgstr "Działanie"
@ -105,6 +108,9 @@ msgstr ""
msgid "Discard input"
msgstr ""
msgid "Discard output"
msgstr ""
msgid "Do not rewrite"
msgstr "Nie przepisuj"
@ -114,6 +120,9 @@ msgstr ""
msgid "Do not track input"
msgstr ""
msgid "Do not track output"
msgstr ""
msgid "Drop invalid packets"
msgstr "Porzuć wadliwe pakiety"
@ -183,6 +192,15 @@ msgstr "Z %s w %s ze źródłem %s"
msgid "From %s in %s with source %s and %s"
msgstr "Z %s w %s ze źródłem %s i %s"
msgid "From %s on <var>this device</var>"
msgstr ""
msgid "From %s on <var>this device</var> with source %s"
msgstr ""
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr ""
msgid "General Settings"
msgstr "Ustawienia ogólne"
@ -316,6 +334,9 @@ msgstr "Inne..."
msgid "Output"
msgstr "Wyjście (Output)"
msgid "Output zone"
msgstr ""
msgid "Passes additional arguments to iptables. Use with care!"
msgstr ""
"Przekazuje dodatkowe argumenty do iptables. Zachowaj szczególną ostrożność!"
@ -540,6 +561,15 @@ msgstr ""
msgid "Tuesday"
msgstr ""
msgid "Unnamed SNAT"
msgstr ""
msgid "Unnamed forward"
msgstr ""
msgid "Unnamed rule"
msgstr ""
msgid "Via %s"
msgstr "Przez %s"

View file

@ -46,6 +46,9 @@ msgstr ""
msgid "Accept input"
msgstr ""
msgid "Accept output"
msgstr ""
msgid "Action"
msgstr "Ação"
@ -103,6 +106,9 @@ msgstr ""
msgid "Discard input"
msgstr ""
msgid "Discard output"
msgstr ""
msgid "Do not rewrite"
msgstr "Não sobrescreva"
@ -112,6 +118,9 @@ msgstr ""
msgid "Do not track input"
msgstr ""
msgid "Do not track output"
msgstr ""
msgid "Drop invalid packets"
msgstr "Descartar pacotes inválidos"
@ -178,6 +187,15 @@ msgstr "Vindo de %s em %s com origem %s"
msgid "From %s in %s with source %s and %s"
msgstr "Vindo de %s em %s com origem %s e %s"
msgid "From %s on <var>this device</var>"
msgstr ""
msgid "From %s on <var>this device</var> with source %s"
msgstr ""
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr ""
msgid "General Settings"
msgstr "Configurações Gerais"
@ -313,6 +331,9 @@ msgstr "Outro..."
msgid "Output"
msgstr "Saída"
msgid "Output zone"
msgstr ""
msgid "Passes additional arguments to iptables. Use with care!"
msgstr "Passa argumentos adicionais para o iptables. Use com cuidado!"
@ -530,6 +551,15 @@ msgstr ""
msgid "Tuesday"
msgstr "Terça-feira"
msgid "Unnamed SNAT"
msgstr ""
msgid "Unnamed forward"
msgstr ""
msgid "Unnamed rule"
msgstr ""
msgid "Via %s"
msgstr "Via %s"

View file

@ -46,6 +46,9 @@ msgstr ""
msgid "Accept input"
msgstr ""
msgid "Accept output"
msgstr ""
msgid "Action"
msgstr "Acção"
@ -104,6 +107,9 @@ msgstr ""
msgid "Discard input"
msgstr ""
msgid "Discard output"
msgstr ""
msgid "Do not rewrite"
msgstr "Não re-escrever"
@ -113,6 +119,9 @@ msgstr ""
msgid "Do not track input"
msgstr ""
msgid "Do not track output"
msgstr ""
msgid "Drop invalid packets"
msgstr "Cancelar pacotes inválidos"
@ -179,6 +188,15 @@ msgstr "De %s em %s com origem %s"
msgid "From %s in %s with source %s and %s"
msgstr "De %s em %s com origem %s e %s"
msgid "From %s on <var>this device</var>"
msgstr ""
msgid "From %s on <var>this device</var> with source %s"
msgstr ""
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr ""
msgid "General Settings"
msgstr "Definições Gerais"
@ -314,6 +332,9 @@ msgstr "Outro..."
msgid "Output"
msgstr "Saída"
msgid "Output zone"
msgstr ""
msgid "Passes additional arguments to iptables. Use with care!"
msgstr "Passa argumentos adicionais para o iptables. Usar com cuidado!"
@ -515,6 +536,15 @@ msgstr ""
msgid "Tuesday"
msgstr ""
msgid "Unnamed SNAT"
msgstr ""
msgid "Unnamed forward"
msgstr ""
msgid "Unnamed rule"
msgstr ""
msgid "Via %s"
msgstr "Via %s"

View file

@ -45,6 +45,9 @@ msgstr ""
msgid "Accept input"
msgstr ""
msgid "Accept output"
msgstr ""
msgid "Action"
msgstr "Acţiune"
@ -99,6 +102,9 @@ msgstr ""
msgid "Discard input"
msgstr ""
msgid "Discard output"
msgstr ""
msgid "Do not rewrite"
msgstr "Nu rescrie"
@ -108,6 +114,9 @@ msgstr ""
msgid "Do not track input"
msgstr ""
msgid "Do not track output"
msgstr ""
msgid "Drop invalid packets"
msgstr "Descarcă pachetele invalide"
@ -174,6 +183,15 @@ msgstr ""
msgid "From %s in %s with source %s and %s"
msgstr ""
msgid "From %s on <var>this device</var>"
msgstr ""
msgid "From %s on <var>this device</var> with source %s"
msgstr ""
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr ""
msgid "General Settings"
msgstr "Setari generale"
@ -300,6 +318,9 @@ msgstr "Altele..."
msgid "Output"
msgstr "Ieşire"
msgid "Output zone"
msgstr ""
msgid "Passes additional arguments to iptables. Use with care!"
msgstr ""
@ -487,6 +508,15 @@ msgstr ""
msgid "Tuesday"
msgstr ""
msgid "Unnamed SNAT"
msgstr ""
msgid "Unnamed forward"
msgstr ""
msgid "Unnamed rule"
msgstr ""
msgid "Via %s"
msgstr ""

View file

@ -48,6 +48,9 @@ msgstr "Принять перенаправление"
msgid "Accept input"
msgstr "Принять входящий трафик"
msgid "Accept output"
msgstr ""
msgid "Action"
msgstr "Действие"
@ -106,6 +109,9 @@ msgstr "Отключить перенаправление"
msgid "Discard input"
msgstr "Отключить входящий трафик"
msgid "Discard output"
msgstr ""
msgid "Do not rewrite"
msgstr "Не перезаписывать"
@ -115,6 +121,9 @@ msgstr "Не отслеживать перенаправление"
msgid "Do not track input"
msgstr "Не отслеживать входящий трафик"
msgid "Do not track output"
msgstr ""
msgid "Drop invalid packets"
msgstr "Не пропускать<br />некорректные пакеты"
@ -181,6 +190,15 @@ msgstr "Из %s в %s с источником %s"
msgid "From %s in %s with source %s and %s"
msgstr "Из %s в %s с источниками %s и %s"
msgid "From %s on <var>this device</var>"
msgstr ""
msgid "From %s on <var>this device</var> with source %s"
msgstr ""
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr ""
msgid "General Settings"
msgstr "Основные настройки"
@ -318,6 +336,9 @@ msgstr "Другое..."
msgid "Output"
msgstr "Исходящий трафик"
msgid "Output zone"
msgstr ""
msgid "Passes additional arguments to iptables. Use with care!"
msgstr ""
"Передаёт дополнительные аргументы таблице iptables. Используйте с "
@ -537,6 +558,15 @@ msgstr ""
msgid "Tuesday"
msgstr "Вторник"
msgid "Unnamed SNAT"
msgstr ""
msgid "Unnamed forward"
msgstr ""
msgid "Unnamed rule"
msgstr ""
msgid "Via %s"
msgstr "Через %s"

View file

@ -41,6 +41,9 @@ msgstr ""
msgid "Accept input"
msgstr ""
msgid "Accept output"
msgstr ""
msgid "Action"
msgstr ""
@ -95,6 +98,9 @@ msgstr ""
msgid "Discard input"
msgstr ""
msgid "Discard output"
msgstr ""
msgid "Do not rewrite"
msgstr ""
@ -104,6 +110,9 @@ msgstr ""
msgid "Do not track input"
msgstr ""
msgid "Do not track output"
msgstr ""
msgid "Drop invalid packets"
msgstr ""
@ -170,6 +179,15 @@ msgstr ""
msgid "From %s in %s with source %s and %s"
msgstr ""
msgid "From %s on <var>this device</var>"
msgstr ""
msgid "From %s on <var>this device</var> with source %s"
msgstr ""
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr ""
msgid "General Settings"
msgstr ""
@ -296,6 +314,9 @@ msgstr ""
msgid "Output"
msgstr ""
msgid "Output zone"
msgstr ""
msgid "Passes additional arguments to iptables. Use with care!"
msgstr ""
@ -483,6 +504,15 @@ msgstr ""
msgid "Tuesday"
msgstr ""
msgid "Unnamed SNAT"
msgstr ""
msgid "Unnamed forward"
msgstr ""
msgid "Unnamed rule"
msgstr ""
msgid "Via %s"
msgstr ""

View file

@ -42,6 +42,9 @@ msgstr ""
msgid "Accept input"
msgstr ""
msgid "Accept output"
msgstr ""
msgid "Action"
msgstr "Åtgärd"
@ -96,6 +99,9 @@ msgstr ""
msgid "Discard input"
msgstr ""
msgid "Discard output"
msgstr ""
msgid "Do not rewrite"
msgstr "Skriv inte om igen"
@ -105,6 +111,9 @@ msgstr ""
msgid "Do not track input"
msgstr ""
msgid "Do not track output"
msgstr ""
msgid "Drop invalid packets"
msgstr "Släpp ogiltiga paket"
@ -171,6 +180,15 @@ msgstr "Från %s i %s med källa %s"
msgid "From %s in %s with source %s and %s"
msgstr "Från %s i %s med källa %s och %s"
msgid "From %s on <var>this device</var>"
msgstr ""
msgid "From %s on <var>this device</var> with source %s"
msgstr ""
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr ""
msgid "General Settings"
msgstr "Generella inställningar"
@ -302,6 +320,9 @@ msgstr "Andra..."
msgid "Output"
msgstr "Utmatning"
msgid "Output zone"
msgstr ""
msgid "Passes additional arguments to iptables. Use with care!"
msgstr ""
@ -489,6 +510,15 @@ msgstr ""
msgid "Tuesday"
msgstr "Tisdag"
msgid "Unnamed SNAT"
msgstr ""
msgid "Unnamed forward"
msgstr ""
msgid "Unnamed rule"
msgstr ""
msgid "Via %s"
msgstr "Via %s"

View file

@ -34,6 +34,9 @@ msgstr ""
msgid "Accept input"
msgstr ""
msgid "Accept output"
msgstr ""
msgid "Action"
msgstr ""
@ -88,6 +91,9 @@ msgstr ""
msgid "Discard input"
msgstr ""
msgid "Discard output"
msgstr ""
msgid "Do not rewrite"
msgstr ""
@ -97,6 +103,9 @@ msgstr ""
msgid "Do not track input"
msgstr ""
msgid "Do not track output"
msgstr ""
msgid "Drop invalid packets"
msgstr ""
@ -163,6 +172,15 @@ msgstr ""
msgid "From %s in %s with source %s and %s"
msgstr ""
msgid "From %s on <var>this device</var>"
msgstr ""
msgid "From %s on <var>this device</var> with source %s"
msgstr ""
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr ""
msgid "General Settings"
msgstr ""
@ -289,6 +307,9 @@ msgstr ""
msgid "Output"
msgstr ""
msgid "Output zone"
msgstr ""
msgid "Passes additional arguments to iptables. Use with care!"
msgstr ""
@ -476,6 +497,15 @@ msgstr ""
msgid "Tuesday"
msgstr ""
msgid "Unnamed SNAT"
msgstr ""
msgid "Unnamed forward"
msgstr ""
msgid "Unnamed rule"
msgstr ""
msgid "Via %s"
msgstr ""

View file

@ -41,6 +41,9 @@ msgstr ""
msgid "Accept input"
msgstr ""
msgid "Accept output"
msgstr ""
msgid "Action"
msgstr ""
@ -95,6 +98,9 @@ msgstr ""
msgid "Discard input"
msgstr ""
msgid "Discard output"
msgstr ""
msgid "Do not rewrite"
msgstr ""
@ -104,6 +110,9 @@ msgstr ""
msgid "Do not track input"
msgstr ""
msgid "Do not track output"
msgstr ""
msgid "Drop invalid packets"
msgstr ""
@ -170,6 +179,15 @@ msgstr ""
msgid "From %s in %s with source %s and %s"
msgstr ""
msgid "From %s on <var>this device</var>"
msgstr ""
msgid "From %s on <var>this device</var> with source %s"
msgstr ""
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr ""
msgid "General Settings"
msgstr ""
@ -296,6 +314,9 @@ msgstr ""
msgid "Output"
msgstr ""
msgid "Output zone"
msgstr ""
msgid "Passes additional arguments to iptables. Use with care!"
msgstr ""
@ -483,6 +504,15 @@ msgstr ""
msgid "Tuesday"
msgstr ""
msgid "Unnamed SNAT"
msgstr ""
msgid "Unnamed forward"
msgstr ""
msgid "Unnamed rule"
msgstr ""
msgid "Via %s"
msgstr ""

View file

@ -1,7 +1,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"PO-Revision-Date: 2012-12-29 12:53+0200\n"
"PO-Revision-Date: 2018-07-01 23:45+0300\n"
"Last-Translator: Yurii <yuripet@gmail.com>\n"
"Language-Team: none\n"
"Language: uk\n"
@ -10,7 +10,6 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%"
"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Pootle 2.0.6\n"
msgid "%s in %s"
msgstr "%s у %s"
@ -22,13 +21,13 @@ msgid "%s, %s in %s"
msgstr "%s, %s у %s"
msgid "(Unnamed Entry)"
msgstr "(Запис без імені)"
msgstr "(Запис без назви)"
msgid "(Unnamed Rule)"
msgstr "(Правило без імені)"
msgstr "(Правило без назви)"
msgid "(Unnamed SNAT)"
msgstr "(SNAT без імені)"
msgstr "(SNAT без назви)"
msgid "<var>%d</var> pkts. per <var>%s</var>"
msgstr "<var>%d</var> пакетів за <var>%s</var>"
@ -40,10 +39,13 @@ msgid "<var>%s</var> and limit to %s"
msgstr "<var>%s</var> з лімітом %s"
msgid "Accept forward"
msgstr ""
msgstr "Приймати переспрямовування"
msgid "Accept input"
msgstr ""
msgstr "Приймати вхідний"
msgid "Accept output"
msgstr "Приймати вихідний"
msgid "Action"
msgstr "Дія"
@ -58,10 +60,10 @@ msgid "Advanced Settings"
msgstr "Розширені настройки"
msgid "Allow forward from <em>source zones</em>:"
msgstr "Дозволити спрямовування від <em>зон-джерел</em>:"
msgstr "Дозволити переспрямовування від <em>зон джерела</em>:"
msgid "Allow forward to <em>destination zones</em>:"
msgstr "Дозволити спрямовування до <em>зон призначення</em>:"
msgstr "Дозволити переспрямовування до <em>зон призначення</em>:"
msgid "Any"
msgstr "Будь-який"
@ -95,22 +97,28 @@ msgid "Destination zone"
msgstr "Зона призначення"
msgid "Disable"
msgstr ""
msgstr "Вимкнути"
msgid "Discard forward"
msgstr ""
msgstr "Відкидати переспрямовування"
msgid "Discard input"
msgstr ""
msgstr "Відкидати вхідний"
msgid "Discard output"
msgstr "Відкидати вихідний"
msgid "Do not rewrite"
msgstr "Не перезаписувати"
msgid "Do not track forward"
msgstr ""
msgstr "Не відслідковувати переспрямовування"
msgid "Do not track input"
msgstr ""
msgstr "Не відслідковувати вхідний"
msgid "Do not track output"
msgstr "Не відслідковувати вихідний"
msgid "Drop invalid packets"
msgstr "Відкидати помилкові пакети"
@ -149,7 +157,7 @@ msgid "Firewall - Custom Rules"
msgstr "Брандмауер — Настроювані правила"
msgid "Firewall - Port Forwards"
msgstr "Брандмауер — Спрямовування портів"
msgstr "Брандмауер — Переспрямовування портів"
msgid "Firewall - Traffic Rules"
msgstr "Брандмауер — Правила трафіка"
@ -161,22 +169,31 @@ msgid "Force connection tracking"
msgstr "Увімкнути відстеження з'єднань"
msgid "Forward"
msgstr "Спрямовування"
msgstr "Переспрямовування"
msgid "Forward to"
msgstr "спрямовування до"
msgstr "переспрямовування до"
msgid "Friday"
msgstr ""
msgstr "П'ятниця"
msgid "From %s in %s"
msgstr "%s у %s"
msgid "From %s in %s with source %s"
msgstr "%s у %s з вихідним %s"
msgstr "%s у %s з джерелом %s"
msgid "From %s in %s with source %s and %s"
msgstr "%s у %s з вихідним %s та %s"
msgstr "%s у %s з джерелом %s та %s"
msgid "From %s on <var>this device</var>"
msgstr "Від %s на <var>цьому пристрої</var>"
msgid "From %s on <var>this device</var> with source %s"
msgstr "Від %s на <var>цьому пристрої</var> з джерелом %s"
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr "Від %s на <var>цьому пристрої</var> з джерелом %s та %s"
msgid "General Settings"
msgstr "Загальні настройки"
@ -185,13 +202,13 @@ msgid "Hardware flow offloading"
msgstr ""
msgid "IP"
msgstr ""
msgstr "IP-адреса"
msgid "IP range"
msgstr ""
msgstr "Діапазон IP"
msgid "IPs"
msgstr ""
msgstr "IP-адреси"
msgid "IPv4"
msgstr "IPv4"
@ -212,7 +229,7 @@ msgid "Input"
msgstr "Вхідний"
msgid "Inter-Zone Forwarding"
msgstr "Спрямовування крізь зони"
msgstr "Переспрямовування між зонами"
msgid "Internal IP address"
msgstr "Внутрішня IP-адреса"
@ -227,10 +244,10 @@ msgid "Limit log messages"
msgstr "Обмеження повідомлень журналу"
msgid "MAC"
msgstr ""
msgstr "MAC-адреса"
msgid "MACs"
msgstr ""
msgstr "MAC-адреси"
msgid "MSS clamping"
msgstr "Затискання MSS"
@ -246,8 +263,8 @@ msgstr "Зіставляти ICMP типу"
msgid "Match forwarded traffic to the given destination port or port range."
msgstr ""
"Зіставляти трафік, що спрямовується на заданий порт призначення або діапазон "
"портів."
"Зіставляти трафік, що переспрямовується на заданий порт призначення або "
"діапазон портів."
msgid ""
"Match incoming traffic directed at the given destination port or port range "
@ -264,10 +281,10 @@ msgstr ""
"діапазоні портів вузла клієнта."
msgid "Monday"
msgstr ""
msgstr "Понеділок"
msgid "Month Days"
msgstr ""
msgstr "Дні місяця"
msgid "Name"
msgstr "Ім'я"
@ -276,13 +293,13 @@ msgid "New SNAT rule"
msgstr "Нове правило SNAT"
msgid "New forward rule"
msgstr "Нове правило спрямовування"
msgstr "Нове правило переспрямовування"
msgid "New input rule"
msgstr "Нове вхідне правило"
msgid "New port forward"
msgstr "Нове спрямовування порту"
msgstr "Нове переспрямовування порту"
msgid "New source NAT"
msgstr "Новий NAT джерела"
@ -312,18 +329,21 @@ msgstr "Інше..."
msgid "Output"
msgstr "Вихідний"
msgid "Output zone"
msgstr "Вихідна зона"
msgid "Passes additional arguments to iptables. Use with care!"
msgstr ""
"Передача додаткових аргументів для IPTables. Використовуйте з обережністю!"
msgid "Port Forwards"
msgstr "Спрямовування портів"
msgstr "Переспрямовування портів"
msgid ""
"Port forwarding allows remote computers on the Internet to connect to a "
"specific computer or service within the private LAN."
msgstr ""
"Спрямовування портів дозволяє віддаленим комп'ютерам з Інтернету "
"Переспрямовування портів дозволяє віддаленим комп'ютерам з Інтернету "
"підключатися до певного комп'ютера або служби у приватній мережі."
msgid "Protocol"
@ -338,22 +358,28 @@ msgid "Redirect matched incoming traffic to the specified internal host"
msgstr "Переспрямувати відповідний вхідний трафік на заданий внутрішній вузол"
msgid "Refuse forward"
msgstr ""
msgstr "Відхиляти переспрямовування"
msgid "Refuse input"
msgstr ""
msgstr "Відхиляти вхідний"
msgid "Refuse output"
msgstr "Відхиляти вихідний"
msgid "Requires hardware NAT support. Implemented at least for mt7621"
msgstr "Необхідна апаратна підтримка NAT. Впроваджено принаймні для mt7621"
msgid "Requires hardware NAT support. Implemented at least for mt7621"
msgstr ""
msgid "Restart Firewall"
msgstr ""
msgstr "Перезавантажити брандмауер"
msgid "Restrict Masquerading to given destination subnets"
msgstr "Обмежити підміну заданими підмережами призначення"
msgid "Restrict Masquerading to given source subnets"
msgstr "Обмежити підміну заданими вихідними підмережами"
msgstr "Обмежити підміну заданими підмережами джерела"
msgid "Restrict to address family"
msgstr "Обмежити сімейство протоколів"
@ -369,19 +395,22 @@ msgstr ""
"порожнім, щоб переписувати тільки IP-адресу."
msgid "Rewrite to source %s"
msgstr "перезапис на вихідний %s"
msgstr "перезапис на джерело %s"
msgid "Rewrite to source %s, %s"
msgstr "перезапис на вихідний %s, %s"
msgstr "перезапис на джерело %s, %s"
msgid "Routing/NAT Offloading"
msgstr "Розвантаження маршрутизації/NAT"
msgid "Routing/NAT Offloading"
msgstr ""
msgid "Rule is disabled"
msgstr ""
msgstr "Правило вимкнено"
msgid "Rule is enabled"
msgstr ""
msgstr "Правило ввімкнено"
msgid "SNAT IP address"
msgstr "IP-адреса SNAT"
@ -390,7 +419,13 @@ msgid "SNAT port"
msgstr "Порт SNAT"
msgid "Saturday"
msgstr ""
msgstr "Субота"
msgid "Software based offloading for routing/NAT"
msgstr "Програмне розвантаження для маршрутизації/NAT"
msgid "Software flow offloading"
msgstr "Програмне розвантаження потоку"
msgid "Software based offloading for routing/NAT"
msgstr ""
@ -423,22 +458,22 @@ msgid "Source port"
msgstr "Порт джерела"
msgid "Source zone"
msgstr "Зона-джерело"
msgstr "Зона джерела"
msgid "Start Date (yyyy-mm-dd)"
msgstr ""
msgstr "Дата початку (рррр-мм-дд)"
msgid "Start Time (hh:mm:ss)"
msgstr ""
msgstr "Час початку (гг:хх:сс)"
msgid "Stop Date (yyyy-mm-dd)"
msgstr ""
msgstr "Дата зупинки (рррр-мм-дд)"
msgid "Stop Time (hh:mm:ss)"
msgstr ""
msgstr "Час зупинки (гг:хх:сс)"
msgid "Sunday"
msgstr ""
msgstr "Неділя"
msgid ""
"The firewall creates zones over your network interfaces to control network "
@ -455,19 +490,21 @@ msgid ""
"rule is <em>unidirectional</em>, e.g. a forward from lan to wan does "
"<em>not</em> imply a permission to forward from wan to lan as well."
msgstr ""
"Опції, наведені нижче, управляють політиками спрямовування між цією (%s) та "
"іншими зонами. <em>Зони призначення</em> покриваються трафіком, що "
"<strong>виходить з %q</strong>. <em>Зони-джерела</em> покриваються трафіком "
"з інших зон, <strong>спрямованим на %q</strong>. Правила спрямування є "
"<em>односпрямованим</em>, тобто, спрямування від LAN до WAN <em>не</em> "
"означає, що є також дозвіл спрямовувати від WAN в LAN."
"Опції, наведені нижче, керують політиками переспрямовування між цією (%s) та "
"іншими зонами. <em>Зони призначення</em> покриваються переспрямованим "
"трафіком, що <strong>виходить з %q</strong>. <em>Зони джерела</em> "
"покриваються трафіком з інших зон, <strong>переспрямованим на %q</strong>. "
"Правило переспрямовування є <em>односпрямованим</em>, тобто, спрямовування "
"від LAN до WAN <em>не</em> означає, що є також дозвіл спрямовувати від WAN "
"до LAN."
msgid ""
"This page allows you to change advanced properties of the port forwarding "
"entry. In most cases there is no need to modify those settings."
msgstr ""
"На цій сторінці можна змінити додаткові властивості елемента спрямовування "
"портів. У більшості випадків змінювати ці параметри немає необхідності."
"На цій сторінці можна змінити додаткові властивості елемента "
"переспрямовування портів. У більшості випадків змінювати ці параметри немає "
"потреби."
msgid ""
"This page allows you to change advanced properties of the traffic rule "
@ -476,7 +513,6 @@ msgstr ""
"На цій сторінці можна змінити додаткові властивості елемента правил трафіка, "
"таких як відповідні параметри джерела та вузлів призначення."
#, fuzzy
msgid ""
"This section defines common properties of %q. The <em>input</em> and "
"<em>output</em> options set the default policies for traffic entering and "
@ -486,15 +522,15 @@ msgid ""
msgstr ""
"Цей розділ визначає загальні властивості %q. Параметри <em>вхідний</em> і "
"<em>вихідний</em> задають типову політику для трафіку на вході й виході з "
"цієї зони, а параметр \"спрямовування\" описує політику спрямовування "
"трафіку між різними мережами в межах зони. Пункт <em>вкриті мережі</em> "
"цієї зони, а параметр \"переспрямовування\" описує політику спрямовування "
"трафіку між різними мережами в межах зони. Пункт <em>Покриті мережі</em> "
"визначає, які доступні мережі є членами цієї зони."
msgid "Thursday"
msgstr ""
msgstr "Четвер"
msgid "Time in UTC"
msgstr ""
msgstr "Час в UTC"
msgid "To %s at %s on <var>this device</var>"
msgstr "%s на %s <var>цього пристрою</var>"
@ -527,7 +563,16 @@ msgstr ""
"порти WAN на маршрутизаторі."
msgid "Tuesday"
msgstr ""
msgstr "Вівторок"
msgid "Unnamed SNAT"
msgstr "SNAT без назви"
msgid "Unnamed forward"
msgstr "Переспрямовування без назви"
msgid "Unnamed rule"
msgstr "Правило без назви"
msgid "Via %s"
msgstr "Через %s"
@ -536,10 +581,10 @@ msgid "Via %s at %s"
msgstr "Через %s на %s"
msgid "Wednesday"
msgstr ""
msgstr "Середа"
msgid "Week Days"
msgstr ""
msgstr "Дні тижня"
msgid ""
"You may specify multiple by selecting \"-- custom --\" and then entering "
@ -552,7 +597,7 @@ msgid "Zone %q"
msgstr "Зона %q"
msgid "Zone ⇒ Forwardings"
msgstr "Зона ⇒ Спрямовування"
msgstr "Зона ⇒ Переспрямовування"
msgid "Zones"
msgstr "Зони"
@ -573,7 +618,7 @@ msgid "any zone"
msgstr "будь-якій зоні"
msgid "day"
msgstr ""
msgstr "день"
msgid "don't track"
msgstr "не відстеж."
@ -582,31 +627,31 @@ msgid "drop"
msgstr "опускати"
msgid "hour"
msgstr ""
msgstr "година"
msgid "minute"
msgstr ""
msgstr "хвилина"
msgid "not"
msgstr ""
msgstr "не"
msgid "port"
msgstr ""
msgstr "порт"
msgid "ports"
msgstr ""
msgstr "порти"
msgid "reject"
msgstr "відкидати"
msgid "second"
msgstr ""
msgstr "секунда"
msgid "traffic"
msgstr ""
msgstr "трафік"
msgid "type"
msgstr ""
msgstr "типом"
msgid "types"
msgstr ""
msgstr "типами"

View file

@ -46,6 +46,9 @@ msgstr ""
msgid "Accept input"
msgstr ""
msgid "Accept output"
msgstr ""
msgid "Action"
msgstr "Action"
@ -101,6 +104,9 @@ msgstr ""
msgid "Discard input"
msgstr ""
msgid "Discard output"
msgstr ""
msgid "Do not rewrite"
msgstr ""
@ -110,6 +116,9 @@ msgstr ""
msgid "Do not track input"
msgstr ""
msgid "Do not track output"
msgstr ""
msgid "Drop invalid packets"
msgstr "Bỏ qua nhưng gói không hợp lý"
@ -177,6 +186,15 @@ msgstr ""
msgid "From %s in %s with source %s and %s"
msgstr ""
msgid "From %s on <var>this device</var>"
msgstr ""
msgid "From %s on <var>this device</var> with source %s"
msgstr ""
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr ""
msgid "General Settings"
msgstr ""
@ -306,6 +324,9 @@ msgstr ""
msgid "Output"
msgstr "Output"
msgid "Output zone"
msgstr ""
msgid "Passes additional arguments to iptables. Use with care!"
msgstr ""
@ -498,6 +519,15 @@ msgstr ""
msgid "Tuesday"
msgstr ""
msgid "Unnamed SNAT"
msgstr ""
msgid "Unnamed forward"
msgstr ""
msgid "Unnamed rule"
msgstr ""
msgid "Via %s"
msgstr ""

View file

@ -44,6 +44,9 @@ msgstr "接受转发"
msgid "Accept input"
msgstr "接受入站"
msgid "Accept output"
msgstr ""
msgid "Action"
msgstr "动作"
@ -100,6 +103,9 @@ msgstr "丢弃转发"
msgid "Discard input"
msgstr "丢弃入站"
msgid "Discard output"
msgstr ""
msgid "Do not rewrite"
msgstr "不重写"
@ -109,6 +115,9 @@ msgstr "不跟踪转发"
msgid "Do not track input"
msgstr "不跟踪入站"
msgid "Do not track output"
msgstr ""
msgid "Drop invalid packets"
msgstr "丢弃无效数据包"
@ -175,6 +184,15 @@ msgstr "来自 %s 位于 %s 源于 %s"
msgid "From %s in %s with source %s and %s"
msgstr "来自 %s 位于 %s 源端口 %s 源 MAC %s"
msgid "From %s on <var>this device</var>"
msgstr ""
msgid "From %s on <var>this device</var> with source %s"
msgstr ""
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr ""
msgid "General Settings"
msgstr "基本设置"
@ -301,6 +319,9 @@ msgstr "其它..."
msgid "Output"
msgstr "出站数据"
msgid "Output zone"
msgstr ""
msgid "Passes additional arguments to iptables. Use with care!"
msgstr "传递到 iptables 的额外参数。小心使用!"
@ -500,6 +521,15 @@ msgstr ""
msgid "Tuesday"
msgstr "星期二"
msgid "Unnamed SNAT"
msgstr ""
msgid "Unnamed forward"
msgstr ""
msgid "Unnamed rule"
msgstr ""
msgid "Via %s"
msgstr "通过 %s"

View file

@ -44,6 +44,9 @@ msgstr ""
msgid "Accept input"
msgstr ""
msgid "Accept output"
msgstr ""
msgid "Action"
msgstr "動作"
@ -100,6 +103,9 @@ msgstr ""
msgid "Discard input"
msgstr ""
msgid "Discard output"
msgstr ""
msgid "Do not rewrite"
msgstr "不重寫"
@ -109,6 +115,9 @@ msgstr ""
msgid "Do not track input"
msgstr ""
msgid "Do not track output"
msgstr ""
msgid "Drop invalid packets"
msgstr "丟棄無效資料包"
@ -175,6 +184,15 @@ msgstr "來自 %s 位於 %s 源於 %s"
msgid "From %s in %s with source %s and %s"
msgstr "來自 %s 位於 %s 源埠 %s 源 MAC %s"
msgid "From %s on <var>this device</var>"
msgstr ""
msgid "From %s on <var>this device</var> with source %s"
msgstr ""
msgid "From %s on <var>this device</var> with source %s and %s"
msgstr ""
msgid "General Settings"
msgstr "基本設定"
@ -301,6 +319,9 @@ msgstr "其它..."
msgid "Output"
msgstr "出站資料"
msgid "Output zone"
msgstr ""
msgid "Passes additional arguments to iptables. Use with care!"
msgstr "傳遞到 iptables 的額外引數。小心使用!"
@ -499,6 +520,15 @@ msgstr ""
msgid "Tuesday"
msgstr "星期二"
msgid "Unnamed SNAT"
msgstr ""
msgid "Unnamed forward"
msgstr ""
msgid "Unnamed rule"
msgstr ""
msgid "Via %s"
msgstr "通過 %s"

View file

@ -11,7 +11,6 @@ local has_ping6 = fs.access("/bin/ping6") or fs.access("/usr/bin/ping6")
local has_traceroute6 = fs.access("/usr/bin/traceroute6")
%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript">//<![CDATA[
var stxhr = new XHR();

View file

@ -5,13 +5,12 @@ XHR.poll(5, '<%=url('admin/telephony/status')%>', null,
var tb = document.getElementById('telephony_status_table');
if (st && tb)
{
tb.deleteRow(1);
var tr = tb.insertRow(-1);
tr.className = 'cbi-section-table-row cbi-rowstyle-1';
tr.insertCell(-1).innerHTML = st.status;
tr.insertCell(-1).innerHTML = st.line1;
tr.insertCell(-1).innerHTML = st.line2;
tb.removeChild(tb.firstChild);
tb.appendChild(E('<div class="tr cbi-section-table-row cbi-rowstyle-1">', [
E('<div class="td">', st.status),
E('<div class="td">', st.line1),
E('<div class="td">', st.line2)
]));
}
}
);
@ -19,14 +18,14 @@ XHR.poll(5, '<%=url('admin/telephony/status')%>', null,
<fieldset class="cbi-section">
<legend><%:Current Telephony State%></legend>
<table class="cbi-section-table" id="telephony_status_table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Uplink%></th>
<th class="cbi-section-table-cell"><%:Port1%></th>
<th class="cbi-section-table-cell"><%:Port2%></th>
</tr>
<tr class="cbi-section-table-row">
<td colspan="5"><em><br /><%:Collecting data...%></em></td>
</tr>
</table>
<div class="table cbi-section-table" id="telephony_status_table">
<div class="tr cbi-section-table-titles">
<div class="th cbi-section-table-cell"><%:Uplink%></div>
<div class="th cbi-section-table-cell"><%:Port1%></div>
<div class="th cbi-section-table-cell"><%:Port2%></div>
</div>
<div class="tr cbi-section-table-row">
<div class="td" colspan="5"><em><br /><%:Collecting data...%></em></div>
</div>
</div>
</fieldset>

View file

@ -7,7 +7,7 @@
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LXC management Web UI
LUCI_DEPENDS:=+luci-mod-admin-full +lxc +lxc-attach +lxc-console +lxc-create +liblxc +rpcd-mod-lxc +getopt
LUCI_DEPENDS:=+luci-mod-admin-full +lxc +lxc-attach +lxc-console +lxc-create +liblxc +rpcd-mod-lxc +getopt +!LXC_BUSYBOX_OPTIONS:tar
LUCI_PKGARCH:=all
PKG_MAINTAINER:=Petar Koretic <petar.koretic@sartura.hr>

View file

@ -14,74 +14,44 @@ Author: Petar Koretic <petar.koretic@sartura.hr>
]]--
local uci = require "luci.model.uci"
local util = require "luci.util"
local nixio = require "nixio"
module("luci.controller.lxc", package.seeall)
function fork_exec(command)
local pid = nixio.fork()
if pid > 0 then
return
elseif pid == 0 then
-- change to root dir
nixio.chdir("/")
-- patch stdin, out, err to /dev/null
local null = nixio.open("/dev/null", "w+")
if null then
nixio.dup(null, nixio.stderr)
nixio.dup(null, nixio.stdout)
nixio.dup(null, nixio.stdin)
if null:fileno() > 2 then
null:close()
end
end
-- replace with target command
nixio.exec("/bin/sh", "-c", command)
end
end
local uci = require "luci.model.uci".cursor()
local util = require "luci.util"
local nx = require "nixio"
local url = util.shellquote(uci:get("lxc", "lxc", "url"))
function index()
if not nixio.fs.access("/etc/config/lxc") then
return
end
page = node("admin", "services", "lxc")
page.target = cbi("lxc")
page.title = _("LXC Containers")
page.order = 70
page = entry({"admin", "services", "lxc_create"}, call("lxc_create"), nil)
page.leaf = true
page = entry({"admin", "services", "lxc_action"}, call("lxc_action"), nil)
page.leaf = true
page = entry({"admin", "services", "lxc_get_downloadable"}, call("lxc_get_downloadable"), nil)
page.leaf = true
page = entry({"admin", "services", "lxc_configuration_get"}, call("lxc_configuration_get"), nil)
page.leaf = true
page = entry({"admin", "services", "lxc_configuration_set"}, call("lxc_configuration_set"), nil)
page.leaf = true
entry({"admin", "services", "lxc_create"}, call("lxc_create"), nil).leaf = true
entry({"admin", "services", "lxc_action"}, call("lxc_action"), nil).leaf = true
entry({"admin", "services", "lxc_get_downloadable"}, call("lxc_get_downloadable"), nil).leaf = true
entry({"admin", "services", "lxc_configuration_get"}, call("lxc_configuration_get"), nil).leaf = true
entry({"admin", "services", "lxc_configuration_set"}, call("lxc_configuration_set"), nil).leaf = true
end
function lxc_get_downloadable()
local target = lxc_get_arch_target()
local target = lxc_get_arch_target(url)
local ssl_status = lxc_get_ssl_status()
local templates = {}
local f = io.popen('sh /usr/share/lxc/templates/lxc-download --list --no-validate --server %s'
% util.shellquote(uci.cursor():get("lxc", "lxc", "url")), 'r')
local f = io.popen('sh /usr/share/lxc/templates/lxc-download --list %s --server %s 2>/dev/null'
%{ ssl_status, url }, 'r')
local line
for line in f:lines() do
local dist, version, dist_target = line:match("^(%S+)%s+(%S+)%s+(%S+)%s+default%s+%S+$")
if dist and version and dist_target == target then
if dist and version and dist_target and dist_target == target then
templates[#templates+1] = "%s:%s" %{ dist, version }
end
end
f:close()
luci.http.prepare_content("application/json")
@ -90,24 +60,21 @@ end
function lxc_create(lxc_name, lxc_template)
luci.http.prepare_content("text/plain")
if not pcall(dofile, "/etc/openwrt_release") then
return luci.http.write("1")
local path = lxc_get_config_path()
if not path then
return
end
local ssl_status = lxc_get_ssl_status()
local lxc_dist, lxc_release = lxc_template:match("^(.+):(.+)$")
luci.sys.call('/usr/bin/lxc-create --quiet --name %s --bdev best --template download -- --dist %s --release %s --arch %s --server %s %s'
%{ lxc_name, lxc_dist, lxc_release, lxc_get_arch_target(url), url, ssl_status })
luci.http.write(util.ubus("lxc", "create", {
name = lxc_name,
template = "download",
args = {
"--server", uci.cursor():get("lxc", "lxc", "url"),
"--no-validate",
"--dist", lxc_dist,
"--release", lxc_release,
"--arch", lxc_get_arch_target()
}
}))
while (nx.fs.access(path .. lxc_name .. "/partial")) do
nx.nanosleep(1)
end
luci.http.write("0")
end
function lxc_action(lxc_action, lxc_name)
@ -121,11 +88,28 @@ function lxc_get_config_path()
local f = io.open("/etc/lxc/lxc.conf", "r")
local content = f:read("*all")
f:close()
local ret = content:match('^%s*lxc.lxcpath%s*=%s*([^%s]*)')
if ret then
return ret .. "/"
if nx.fs.access(ret) then
local min_space = tonumber(uci:get("lxc", "lxc", "min_space")) or 100000
local free_space = tonumber(util.exec("df " ..ret.. " | awk '{if(NR==2)print $4}'"))
if free_space and free_space >= min_space then
local min_temp = tonumber(uci:get("lxc", "lxc", "min_temp")) or 100000
local free_temp = tonumber(util.exec("df /tmp | awk '{if(NR==2)print $4}'"))
if free_temp and free_temp >= min_temp then
return ret .. "/"
else
util.perror("lxc error: not enough temporary space (< " ..min_temp.. " KB)")
end
else
util.perror("lxc error: not enough space (< " ..min_space.. " KB)")
end
else
util.perror("lxc error: directory not found")
end
else
return "/srv/lxc/"
util.perror("lxc error: config path is empty")
end
end
@ -142,15 +126,16 @@ end
function lxc_configuration_set(lxc_name)
luci.http.prepare_content("text/plain")
local lxc_configuration = luci.http.formvalue("lxc_configuration")
local lxc_configuration = luci.http.formvalue("lxc_conf")
if lxc_configuration == nil then
return luci.http.write("1")
util.perror("lxc error: config formvalue is empty")
return
end
local f, err = io.open(lxc_get_config_path() .. lxc_name .. "/config","w+")
if not f then
return luci.http.write("2")
util.perror("lxc error: config file not found")
return
end
f:write(lxc_configuration)
@ -159,22 +144,32 @@ function lxc_configuration_set(lxc_name)
luci.http.write("0")
end
function lxc_get_arch_target()
local target = nixio.uname().machine
local target_map = {
armv5 = "armel",
armv6 = "armel",
armv7 = "armhf",
armv8 = "arm64",
x86_64 = "amd64"
}
local k, v
for k, v in pairs(target_map) do
if target:find(k) then
return v
function lxc_get_arch_target(url)
local target = nx.uname().machine
if url and url:match("images.linuxcontainers.org") then
local target_map = {
armv5 = "armel",
armv6 = "armel",
armv7 = "armhf",
armv8 = "arm64",
x86_64 = "amd64"
}
local k, v
for k, v in pairs(target_map) do
if target:find(k) then
return v
end
end
end
return target
end
function lxc_get_ssl_status()
local ssl_enabled = uci:get("lxc", "lxc", "ssl_enabled")
local ssl_status = "--no-validate"
if ssl_enabled and ssl_enabled == "1" then
ssl_status = ""
end
return ssl_status
end

View file

@ -14,18 +14,35 @@ Author: Petar Koretic <petar.koretic@sartura.hr>
]]--
local fs = require "nixio.fs"
m = Map("lxc", translate("LXC Containers"),
translate("<b>Please note:</b> For LXC Containers you need a custom OpenWrt image.<br />")
.. translate("The image should include at least support for 'kernel cgroups', 'kernel namespaces' and 'miscellaneous LXC related options' plus 'kmod-veth' for optional network support."))
m:section(SimpleSection).template = "lxc"
m = Map("lxc", translate("LXC Containers"))
s = m:section(TypedSection, "lxc", translate("Options"))
s.anonymous = true
if fs.access("/etc/config/lxc") then
m:section(SimpleSection).template = "lxc"
o1 = s:option(Value, "url", translate("Containers URL"))
o1:value("images.linuxcontainers.org")
o1:value("repo.turris.cz/lxc", "repo.turris.cz/lxc (SSL req.)")
o1.default = "images.linuxcontainers.org"
o1.rmempty = false
s = m:section(TypedSection, "lxc", translate("Options"))
s.anonymous = true
s.addremove = false
o2 = s:option(Flag, "ssl_enabled", translate("Enable SSL"),
translate("Enable optional SSL encryption support. This requires additional packages like 'wget', 'ca-certificates', 'gnupg' and 'gnupg-utils'."))
o2.default = o2.disabled
o2.rmempty = false
s:option(Value, "url", translate("Containers URL"))
end
o3 = s:option(Value, "min_space", translate("Free Space Threshold"),
translate("Minimum required free space for LXC Container creation in KB"))
o3.default = "100000"
o3.datatype = "min(50000)"
o3.rmempty = false
o4 = s:option(Value, "min_temp", translate("Free Temp Threshold"),
translate("Minimum required free temp space for LXC Container creation in KB"))
o4.default = "100000"
o4.datatype = "min(50000)"
o4.rmempty = false
return m

View file

@ -14,346 +14,371 @@ Author: Petar Koretic <petar.koretic@sartura.hr>
-%>
<fieldset class="cbi-section">
<legend><%:Available Containers%></legend>
<div class="cbi-section-node">
<table id="t_lxc_list" class="cbi-section-table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Name%></th>
<th class="cbi-section-table-cell"><%:Status%></th>
<th class="cbi-section-table-cell"><%:Actions%></th>
</tr>
</table>
</div>
</fieldset>
<%-
local nx = require "nixio"
local target = nx.uname().machine
-%>
<fieldset class="cbi-section">
<div class="cbi-section">
<h3><%:Available Containers%></h3>
<div class="cbi-section-node">
<div class="table cbi-section-table" id="t_lxc_list">
<div class="tr cbi-section-table-titles">
<div class="th cbi-section-table-cell"><%:Name%></div>
<div class="th cbi-section-table-cell"><%:Status%></div>
<div class="th cbi-section-table-cell"><%:Actions%></div>
</div>
</div>
</div>
</div>
<div class="cbi-section">
<span id="lxc-list-output"></span>
</fieldset>
</div>
<hr/>
<fieldset class="cbi-section">
<legend><%:Create New Container%></legend>
<hr />
<div class="cbi-section">
<h3><%:Create New Container%></h3>
<div class="cbi-section-node">
<table id="t_lxc_create" class="cbi-section-table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Name%></th>
<th class="cbi-section-table-cell"><%:Template%></th>
<th class="cbi-section-table-cell"><%:Actions%></th>
</tr>
<tr id="tr_holder">
<td>
<input type="text" id="tx_name" placeholder="<%:Enter new name%>" value='' />
</td>
<td>
<select id="s_template" class="cbi-input-select cbi-button">
</select>
</td>
<td>
<input type="button" id="bt_create" value="<%:Create%>" onclick="lxc_create(tr_holder)" class="cbi-button cbi-button-add" />
<div class="table cbi-section-table" id="t_lxc_create">
<div class="tr cbi-section-table-titles">
<div class="th cbi-section-table-cell"><%:Name%></div>
<div class="th cbi-section-table-cell"><%:Template%></div>
<div class="th cbi-section-table-cell"><%:Actions%></div>
</div>
<div class="tr cbi-section-table-row" id="div_create">
<div class="td"><input class="cbi-input-text" type="text" id="tx_name" placeholder="<%:Enter new name%>" value='' /></div>
<div class="td"><select id="s_template" class="cbi-input-select cbi-button"></select></div>
<div class="td">
<input type="button" id="bt_create" value="<%:Create%>" onclick="lxc_create()" class="cbi-button cbi-button-add" />
<span id="lxc-add-loader" style="display:inline-block; width:16px; height:16px; margin:0 5px"></span>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</fieldset>
</div>
<fieldset class="cbi-section">
<div class="cbi-section">
<span id="lxc-add-output"></span>
</fieldset>
</div>
<hr/>
<hr />
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript">//<![CDATA[
<script type="text/javascript">
//<![CDATA[
window.img = { "red" : "<%=resource%>/cbi/red.gif", "green" : "<%=resource%>/cbi/green.gif", "purple" : "<%=resource%>/cbi/purple.gif" };
window.states = { "STOPPED" : "red", "RUNNING" : "green", "FROZEN" : "purple" };
window.img = { "red" : "<%=resource%>/cbi/red.gif", "green" : "<%=resource%>/cbi/green.gif", "purple" : "<%=resource%>/cbi/purple.gif" }
window.states = { "STOPPED" : "red", "RUNNING" : "green", "FROZEN" : "purple"}
var t_lxc_list = document.getElementById('t_lxc_list');
var loader_html = '<img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" width="16" height="16" style="vertical-align:middle" />';
var output_list = document.getElementById("lxc-list-output");
var output_add = document.getElementById("lxc-add-output");
var loader_add = document.getElementById("lxc-add-loader");
var div_create = document.getElementById("div_create");
var bt_create = div_create.querySelector("#bt_create");
var t_lxc_list = document.getElementById('t_lxc_list');
var loader_html = '<img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" width="16" height="16" style="vertical-align:middle" /> ';
var timeout_msg = 0
var output_list = document.getElementById("lxc-list-output")
var output_add = document.getElementById("lxc-add-output")
var loader_add = document.getElementById("lxc-add-loader")
bt_create.disabled = true;
info_message(output_add, "Template download in progress, please be patient!");
function lxc_create(tr)
function lxc_create()
{
var lxc_name = tr.querySelector("#tx_name").value.trim()
var lxc_template = tr.querySelector("#s_template").value
var bt_create = tr.querySelector("#bt_create")
var lxc_name = div_create.querySelector("#tx_name").value.replace(/[\s!@#$%^&*()+=\[\]{};':"\\|,<>\/?]/g,'');
var lxc_template = div_create.querySelector("#s_template").value;
if (t_lxc_list.querySelector("[data-id='" + lxc_name + "']") != null)
return info_message(output_add, "Container with that name already exists!", 4000)
{
return info_message(output_add, "Container with that name already exists!", 2000);
}
bt_create.disabled = true
output_add.innerHTML = ''
bt_create.disabled = true;
output_add.innerHTML = '';
if (!lxc_template)
{
return set_no_template();
}
if (!lxc_name || !lxc_name.length)
{
bt_create.disabled = false
return info_message(output_add, "Name cannot be empty!", 4000)
bt_create.disabled = false;
return info_message(output_add, "The 'Name' field must not be empty!", 2000);
}
loading(loader_add)
loading(loader_add);
new XHR().get('<%=luci.dispatcher.build_url("admin", "services")%>/lxc_create/' + '%h/%h'.format(lxc_name, lxc_template) , null,
function(x)
{
bt_create.disabled = false
loading(loader_add, 0)
bt_create.disabled = false;
loading(loader_add, 0);
if (!x)
info_message(output_add, "Container creation failed!")
{
info_message(output_add, "Container creation failed!", 2000);
}
})
}
function lxc_create_template(lxc_name, lxc_state)
{
var info_row = t_lxc_list.querySelector("#empty")
if (info_row)
t_lxc_list.deleteRow(1)
if (document.getElementById(lxc_name))
{
return;
}
var actions = ''
actions += '<input type="button" onclick="action_handler(this)" data-action="start" value="<%:Start%>" class="cbi-button cbi-button-apply" />'
actions+= '<input type="button" onclick="action_handler(this)" data-action="stop" value="<%:Stop%>" class="cbi-button cbi-button-reset" />'
actions+= '<input type="button" onclick="action_handler(this)" data-action="destroy" value="<%:Delete%>" class="cbi-button cbi-button-remove" />'
actions+= ' <select class="cbi-input-select cbi-button" onchange="action_more_handler(this)">\
<option selected disabled>more</option>\
info_message(output_list, "");
var actions = '';
actions += '<input type="button" onclick="action_handler(this)" data-action="start" value="<%:Start%>" class="cbi-button cbi-button-apply" />';
actions += '&#160;<input type="button" onclick="action_handler(this)" data-action="stop" value="<%:Stop%>" class="cbi-button cbi-button-reset" />';
actions += '&#160;<input type="button" onclick="action_handler(this)" data-action="destroy" value="<%:Delete%>" class="cbi-button cbi-button-remove" />';
actions += '&#160;<select class="cbi-input-select cbi-button" style="width:10em" onchange="action_more_handler(this)">\
<option selected="selected" disabled="disabled">more</option>\
<option>configure</option>\
<option>freeze</option>\
<option>unfreeze</option>\
<option>reboot</option>\
</select>'
actions+= '<span data-loader style="display:inline-block; width:16px; height:16px; margin:0 5px"></span>'
</select>';
actions += '<span data-loader="" style="display:inline-block; width:16px; height:16px; margin:0 5px"></span>';
var row = t_lxc_list.insertRow(-1)
var cell = row.insertCell(-1)
cell.innerHTML = '%q%h%q'.format("<strong>", lxc_name, "</strong>")
cell.width = "30%"
cell.setAttribute("data-id", lxc_name)
var div0 = document.createElement("div");
div0.className = "tr cbi-section-table-row";
div0.id = lxc_name;
div0.setAttribute("data-id", lxc_name);
cell = row.insertCell(-1)
cell.width = "20%"
cell.innerHTML = "<img src='"+window.img[lxc_state]+"'/>"
var div1 = document.createElement("div");
div1.className = "td";
div1.style.width = "30%";
div1.innerHTML = '%q%h%q'.format("<strong>", lxc_name, "</strong>");
cell = row.insertCell(-1)
cell.width = "50%"
cell.innerHTML = actions
var div2 = document.createElement("div");
div2.className = "td";
div2.style.width = "20%";
div2.innerHTML = "<img src='"+window.img[lxc_state]+"'/>";
var div3 = document.createElement("div");
div3.className = "td";
div3.style.width = "50%";
div3.innerHTML = actions;
document.getElementById("t_lxc_list").appendChild(div0);
div0.appendChild(div1);
div0.appendChild(div2);
div0.appendChild(div3);
}
function action_handler(self)
{
var action = self.getAttribute("data-action");
var bt_action = self;
var action = self.dataset['action'];
var lxc_name = self.parentNode.parentNode.dataset['id'];
var status_img = self.parentNode.parentNode.querySelector('img');
var loader = self.parentNode.querySelector('[data-loader]');
var bt_action = self
var lxc_name = self.parentNode.parentNode.children[0].getAttribute('data-id')
var status_img = self.parentNode.parentNode.querySelector('img')
var loader = self.parentNode.querySelector('[data-loader]')
bt_action.disabled = true
bt_action.disabled = true;
if (action == "stop")
{
loading(loader)
loading(loader);
new XHR().get('<%=luci.dispatcher.build_url("admin", "services")%>/lxc_action/' + '%h/%h'.format(action, lxc_name), null,
function(x, ec)
{
loading(loader, 0)
bt_action.disabled = false
loading(loader, 0);
bt_action.disabled = false;
if (!x || ec)
return info_message(output_list,"Action failed!")
set_status(status_img, "red")
{
return info_message(output_list,"Action failed!", 2000);
}
set_status(status_img, "red");
});
}
else if (action == "start")
{
loading(loader)
loading(loader);
new XHR().get('<%=luci.dispatcher.build_url("admin", "services")%>/lxc_action/' + '%h/%h'.format(action, lxc_name), null,
function(x, data)
{
loading(loader, 0)
bt_action.disabled = false
loading(loader, 0);
bt_action.disabled = false;
//FIXME: uncomment after fixing 'lxc-start'
if (!x /*|| ec */)
return info_message(output_list,"Action failed!")
//FIXME: uncomment after fixing 'lxc-start'
//set_status(status_img, "green")
if (!x || data)
{
return info_message(output_list,"Action failed!", 2000);
}
set_status(status_img, "green");
});
}
else if (action == "destroy")
{
if (!confirm("This will completely remove LXC container from the disk. Are you sure? (container will be stopped if running)"))
return
var div = self.parentNode.parentNode;
var img = div.querySelector('img');
loading(loader)
if (img.getAttribute('src') != window.img["red"])
{
bt_action.disabled = false;
return info_message(output_list,"Container is still running!", 2000);
}
if (!confirm("This will completely remove a stopped LXC container from disk. Are you sure?"))
{
bt_action.disabled = false;
return;
}
loading(loader);
new XHR().get('<%=luci.dispatcher.build_url("admin", "services")%>/lxc_action/' + '%h/%h'.format(action, lxc_name), null,
function(x, ec)
{
loading(loader, 0)
bt_action.disabled = false
loading(loader, 0);
bt_action.disabled = false;
if (!x || ec)
return info_message(output_list,"Action failed!")
var row = self.parentNode.parentNode
row.parentNode.removeChild(row)
{
return info_message(output_list,"Action failed!", 2000);
}
var div = self.parentNode.parentNode;
div.parentNode.removeChild(div);
});
}
}
function lxc_configure_handler(self)
{
var td = self.parentNode
var textarea = td.querySelector('[data-id]')
var lxc_name = textarea.getAttribute('data-id')
var lxc_configuration = textarea.value
var div = self.parentNode;
var textarea = div.querySelector('[data-id]');
var lxc_name = textarea.dataset['id'];
var lxc_conf = textarea.value;
new XHR().post('<%=luci.dispatcher.build_url("admin", "services")%>/lxc_configuration_set/' + lxc_name, "lxc_configuration=" + encodeURIComponent(lxc_configuration) ,
new XHR().post('<%=luci.dispatcher.build_url("admin", "services")%>/lxc_configuration_set/' + lxc_name, "lxc_conf=" + encodeURIComponent(lxc_conf),
function(x)
{
if (!x || x.responseText != "0")
return info_message(output_list,"Action failed!")
info_message(output_list,"LXC configuration updated")
var row = td.parentNode
row.parentNode.removeChild(row)
{
return info_message(output_list,"Action failed!", 2000);
}
info_message(output_list,"LXC configuration updated", 2000);
var rmdiv = div.parentNode;
rmdiv.parentNode.removeChild(rmdiv);
})
}
function lxc_rename_template(lxc_name)
function lxc_configure_template(lxc_name, lxc_conf)
{
var h = '\
<input data-id="'+ lxc_name + '" type="text" placeholder="Enter new name" /> \
<input data-id="bt_confirm" onclick="lxc_rename_handler(this)" type="button" class="cbi-button" value="Confirm" />'
return h
}
function lxc_configure_template(lxc_name, lxc_configuration)
{
var h = '\
<textarea data-id="'+ lxc_name + '" rows="20" style="width:100%">'+ lxc_configuration +'</textarea> \
<input data-id="bt_confirm" onclick="lxc_configure_handler(this)" type="button" class="cbi-button" value="Confirm" />'
return h
<textarea data-id="' + lxc_name + '" rows="20" style="width:600px;font-family:monospace;white-space:pre;overflow-wrap:normal;overflow-x:scroll;">'+ lxc_conf +'</textarea> \
<input data-id="bt_confirm" onclick="lxc_configure_handler(this)" type="button" class="cbi-button" value="Confirm" />';
return h;
}
function action_more_handler(self)
{
var lxc_name = self.parentNode.parentNode.querySelector('[data-id]').getAttribute('data-id')
var loader = self.parentNode.parentNode.querySelector('[data-loader]')
var lxc_name = self.parentNode.parentNode.dataset['id'];
var loader = self.parentNode.querySelector('[data-loader]');
var option = self.options[self.selectedIndex].text;
self.value = "more";
var option = self.options[self.selectedIndex].text
self.value = "more"
switch (option)
switch(option)
{
case "configure":
var tr = document.createElement('tr')
var row = self.parentNode.parentNode
var next_row = row.nextSibling
if (next_row && next_row.getAttribute('data-action') !== null)
row.parentNode.removeChild(next_row)
var div0 = document.createElement('div');
var div1 = self.parentNode.parentNode;
var next_div = div1.nextSibling;
if (next_div && next_div.dataset['action'] !== null)
{
div1.parentNode.removeChild(next_div);
}
new XHR().get('<%=luci.dispatcher.build_url("admin", "services")%>/lxc_configuration_get/' + lxc_name, null,
function(x)
{
tr.innerHTML="<td colspan='" + row.cells.length + "'>" + lxc_configure_template(lxc_name, x.responseText) + "</td>"
tr.setAttribute('data-action','')
row.parentNode.insertBefore(tr, row.nextSibling)
div0.innerHTML="<div>" + lxc_configure_template(lxc_name, x.responseText) + "</div>";
div0.setAttribute('data-action','');
div1.parentNode.insertBefore(div0, div1.nextSibling);
})
break
break;
case "freeze":
var tr = self.parentNode.parentNode
var img = tr.querySelector('img')
var img = self.parentNode.parentNode.querySelector('img');
if(img.getAttribute('src') != window.img["green"])
return info_message(output_list,"Container is not running!")
{
return info_message(output_list,"Container is not running!", 2000);
}
loading(loader);
loading(loader)
new XHR().get('<%=luci.dispatcher.build_url("admin", "services")%>/lxc_action/' + '%h/%h'.format(option, lxc_name), null,
function(x, ec)
{
loading(loader, 0)
if (!x || ec)
return info_message(output_list,"Action failed!")
set_status(img, "purple")
{
return info_message(output_list,"Action failed!", 2000);
}
set_status(img, "purple");
})
break
break;
case "unfreeze":
var tr = self.parentNode.parentNode
var img = tr.querySelector('img')
var img = self.parentNode.parentNode.querySelector('img');
if(img.getAttribute('src') != window.img["purple"])
return info_message(output_list,"Container is not frozen!")
{
return info_message(output_list,"Container is not frozen!", 2000);
}
loading(loader);
loading(loader)
new XHR().get('<%=luci.dispatcher.build_url("admin", "services")%>/lxc_action/' + '%h/%h'.format(option, lxc_name), null,
function(x, ec)
{
loading(loader, 0)
loading(loader, 0);
if (!x || ec)
return info_message(output_list,"Action failed!")
set_status(img, "green")
{
return info_message(output_list,"Action failed!", 2000);
}
set_status(img, "green");
})
break
break;
case "reboot":
var tr = self.parentNode.parentNode
var img = tr.querySelector('img')
var img = self.parentNode.parentNode.querySelector('img');
if(img.getAttribute('src') != window.img["green"])
return info_message(output_list,"Container is not running!")
{
return info_message(output_list,"Container is not running!", 2000);
}
if (!confirm("Are you sure?"))
return
{
return;
}
loading(loader);
loading(loader)
new XHR().get('<%=luci.dispatcher.build_url("admin", "services")%>/lxc_action/' + '%h/%h'.format(option, lxc_name), null,
function(x, ec)
{
loading(loader, 0)
if (!x || ec)
return info_message(output_list,"Action failed!")
info_message(output_list,"LXC rebooted")
{
return info_message(output_list,"Action failed!", 2000);
}
info_message(output_list,"LXC container rebooted", 2000);
})
break
break;
}
}
function set_empty(t_lxc_list)
function set_no_container()
{
if (document.getElementById('empty') !== null)
return
info_message(output_list, "There are no containers available yet.");
}
var row_count = t_lxc_list.rows.length;
while(--row_count) t_lxc_list.deleteRow(row_count);
var row = t_lxc_list.insertRow(-1);
row.id = 'empty'
var cell = row.insertCell(0);
cell.colSpan = 4;
cell.innerHTML = '<em><br />There are no containers available yet.</em>';
function set_no_template()
{
bt_create.disabled = true;
info_message(output_add, "There are no templates for your architecture (<%=target%>) available, please select another containers URL.");
}
function lxc_list_update()
@ -361,90 +386,108 @@ Author: Petar Koretic <petar.koretic@sartura.hr>
XHR.poll(4, '<%=luci.dispatcher.build_url("admin", "services")%>/lxc_action/list', null,
function(x, data)
{
if (!x) return;
if (!x || !data)
{
return;
}
var lxc_count = Object.keys(data).length
if (!data || !lxc_count)
return set_empty(t_lxc_list)
var lxc_count = Object.keys(data).length;
if (!lxc_count)
{
return set_no_container();
}
if (document.getElementById('empty') !== null)
t_lxc_list.deleteRow(1);
var lxcs = t_lxc_list.querySelectorAll('td[data-id]')
var lxc_name_table = {}
var lxcs = t_lxc_list.querySelectorAll('td[data-id]');
var lxc_name_div = {};
for (var i = 0, len = lxcs.length; i < len; i++)
{
var lxc_name = lxcs[i].getAttribute('data-id')
var lxc_name = lxcs[i].dataset['id'];
if (!(lxc_name in data))
{
var row = t_lxc_list.querySelector("[data-id='" + lxc_name + "']").parentNode
row.parentNode.removeChild(row)
continue
var div = t_lxc_list.querySelector("[data-id='" + lxc_name + "']").parentNode;
div.parentNode.removeChild(div);
continue;
}
lxc_name_table[lxc_name] = lxcs[i].parentNode.querySelector('img')
lxc_name_div[lxc_name] = lxcs[i].parentNode.querySelector('img');
}
for(var key in data)
{
var lxc_name = key
var state = window.states[data[key]]
var lxc_name = key;
var state = window.states[data[key]];
if (!(lxc_name in lxc_name_table))
lxc_create_template(lxc_name, state)
else if (state != get_status(lxc_name_table[lxc_name]))
set_status(lxc_name_table[lxc_name], state)
if (!(lxc_name in lxc_name_div))
{
lxc_create_template(lxc_name, state);
}
else if (state != get_status(lxc_name_div[lxc_name]))
{
set_status(lxc_name_div[lxc_name], state);
}
}
})
}
function loading(elem, state)
{
state = (typeof state === 'undefined') ? 1 : state
state = (typeof state === 'undefined') ? 1 : state;
if (state === 1)
elem.innerHTML = loader_html
{
elem.innerHTML = loader_html;
}
else
setTimeout(function() { elem.innerHTML = ''}, 1000)
{
setTimeout(function() { elem.innerHTML = ''}, 2000);
}
}
function set_status(elem, state)
{
state = (typeof state === 'undefined') ? 1 : state
setTimeout(function() { elem.setAttribute('src', window.img[state])}, 300)
state = (typeof state === 'undefined') ? 1 : state;
setTimeout(function() { elem.setAttribute('src', window.img[state])}, 300);
}
function get_status(elem)
{
var src = elem.getAttribute('src')
var src = elem.getAttribute('src');
for (var i in img)
{
if (img[i] == src)
return i
{
return i;
}
}
}
function info_message(output, msg, timeout)
{
timeout = timeout || 3000
output.innerHTML = msg
clearTimeout(timeout_msg)
timeout_msg = setTimeout(function(){ output.innerHTML=""}, timeout);
timeout = timeout || 0;
output.innerHTML = '<em>' + msg + '</em>';
if (timeout > 0)
{
setTimeout(function(){ output.innerHTML=""}, timeout);
}
}
lxc_list_update()
new XHR().get('<%=luci.dispatcher.build_url("admin", "services")%>/lxc_get_downloadable', null,
function(x, data)
{
if (!x) return;
if (!x)
{
return;
}
if (!data)
{
return set_no_template();
}
var lxc_count = Object.keys(data).length;
if (!lxc_count)
{
return set_no_template();
}
var lxc_count = Object.keys(data).length
if (!data || !lxc_count) return;
var select = document.getElementById("s_template");
for(var key in data)
{
@ -453,6 +496,11 @@ Author: Petar Koretic <petar.koretic@sartura.hr>
option.text = data[key].replace(/[_:]/g, ' ');
select.add(option, -1);
}
info_message(output_add, "");
bt_create.disabled = false;
})
//]]></script>
lxc_list_update();
//]]>
</script>

View file

@ -138,10 +138,12 @@ function diagnosticsData(interface, task)
local number = getInterfaceNumber(interface)
local uci = require "luci.model.uci".cursor(nil, "/var/state")
local device = uci:get("network", interface, "ifname")
local nw = require "luci.model.network".init()
local network = nw:get_network(interface)
local device = network and network:ifname()
luci.http.prepare_content("text/plain")
if device ~= "" then
if device then
if task == "ping_gateway" then
local gateway = get_gateway(interface)
if gateway ~= nil then

View file

@ -13,7 +13,6 @@
<li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/status/mwan/troubleshooting")%>"><%:Troubleshooting%></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", "status", "mwan", "detailed_status")%>', null,
function(x)

View file

@ -25,7 +25,6 @@
)
%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript">//<![CDATA[
var stxhr = new XHR();

View file

@ -13,7 +13,6 @@
<li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/status/mwan/troubleshooting")%>"><%:Troubleshooting%></a></li>
</ul>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<div class="cbi-map">
<%+mwan/overview_status_interface%>

View file

@ -13,7 +13,6 @@
<li class="cbi-tab"><a href="<%=luci.dispatcher.build_url("admin/status/mwan/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", "status", "mwan", "troubleshooting_display")%>', null,
function(x)

View file

@ -57,7 +57,7 @@ msgid "Destination port"
msgstr "目标端口"
msgid "Detail"
msgstr ""
msgstr "详细"
msgid "Diagnostics"
msgstr "诊断"
@ -76,7 +76,7 @@ msgid "Enter value in hex, starting with <code>0x</code>"
msgstr "输入十六进制值,以 <code>0x</code> 开头"
msgid "Execute"
msgstr ""
msgstr "执行"
msgid "Expect interface state on up event"
msgstr "在 up 事件发生时的预期接口状态"
@ -103,7 +103,7 @@ msgid "Hotplug ifup"
msgstr "Hotplug ifup"
msgid "INFO: MWAN not running"
msgstr ""
msgstr "信息MWAN 没有运行"
msgid "IPset"
msgstr "IPset"
@ -154,28 +154,28 @@ msgid "Local source interface"
msgstr "本地源接口"
msgid "MWAN - Globals"
msgstr ""
msgstr "MWAN - 全局"
msgid "MWAN - Interfaces"
msgstr ""
msgstr "MWAN - 接口"
msgid "MWAN - Members"
msgstr ""
msgstr "MWAN - 成员"
msgid "MWAN - Notification"
msgstr ""
msgstr "MWAN - 通知"
msgid "MWAN - Policies"
msgstr ""
msgstr "MWAN - 策略"
msgid "MWAN - Rules"
msgstr ""
msgstr "MWAN - 规则"
msgid "MWAN Interface Configuration - %s"
msgstr "MWAN 接口配置 - %s"
msgid "MWAN Interfaces"
msgstr ""
msgstr "MWAN 接口"
msgid "MWAN Member Configuration - %s"
msgstr "MWAN 成员配置 - %s"
@ -187,13 +187,13 @@ msgid "MWAN Rule Configuration - %s"
msgstr "MWAN 规则配置 - %s"
msgid "MWAN Status - Detail"
msgstr ""
msgstr "MWAN Status - 详细"
msgid "MWAN Status - Diagnostics"
msgstr ""
msgstr "MWAN Status - 诊断"
msgid "MWAN Status - Troubleshooting"
msgstr ""
msgstr "MWAN Status - 故障排除"
msgid ""
"MWAN supports up to 252 physical and/or logical interfaces<br />MWAN "
@ -265,7 +265,7 @@ msgid "No MWAN interfaces found"
msgstr "没有找到 MWAN 接口"
msgid "Notification"
msgstr ""
msgstr "通知"
msgid "Offline"
msgstr "离线"
@ -312,8 +312,8 @@ msgstr ""
"“策略”把成员进行分组,告诉 MWAN 如何分配“规则”中使用这一策略的流量<br />拥有"
"较低跃点数的成员将会被优先使用。拥有相同跃点数的成员把流量进行负载均衡。<br /"
">进行负载均衡的成员之间拥有较高比重的成员将会被分配到更多流量。<br />名称允许"
"包括A-Z、a-z、0-9、_ 但是不能有空格。名称应该在 15 个字符以内<br />策略不应"
"与接口、成员、规则中的任意一个设置项使用相同的名称"
"包括 A-Z、a-z、0-9、_ 但是不能有空格。名称应该在 15 个字符以内<br />策略不应"
"与接口、成员、规则中的任意一个设置项使用相同的名称"
msgid "Policy"
msgstr "策略"
@ -344,6 +344,11 @@ msgid ""
"z, 0-9, _ and no spaces<br />Rules may not share the same name as configured "
"interfaces, members or policies"
msgstr ""
"规则指定哪些流量将使用特定的 MWAN 策略<br />规则基于 IP 地址,端口或协议<br /"
">规则从上到下匹配<br />匹配规则以下的规则被忽略<br />不符合任何规则的流量将使"
"用主路由表进行路由<br />目的地为已知(非默认)网络的流量由主路由表处理<br />"
"流量符合规则,但该策略的所有 WAN 接口关闭后都会被失效<br />名称可包含字符 A-"
"Za-z0-9_和空格<br />规则不能与配置的接口、成员或策略共享相同的名称"
msgid "Seconds. Acceptable values: 1-1000000. Defaults to 600 if not set"
msgstr "单位为秒。接受的值1-1000000。留空则使用默认值 600 秒"
@ -364,7 +369,7 @@ msgid "Supports CIDR notation (eg \"192.168.100.0/24\") without quotes"
msgstr "支持 CIDR 记法(例如:\"192.168.100.0/24\")不含引号"
msgid "Task"
msgstr ""
msgstr "任务"
msgid "There are currently %d of %d supported interfaces configured"
msgstr "当前已配置 %d 个接口,最大支持 %d 个"
@ -395,6 +400,14 @@ msgid ""
"Physical device name which interface went up or down (e.g. \"eth0\" or "
"\"wwan0\")<br /><br />"
msgstr ""
"这里允许您修改“/etc/mwan3.user”的内容。<br />该文件在 sysupgrade 期间也会保"
"留。<br /><br />注意:<br />该文件会作为 shell 脚本解释。<br />脚本的第一行必"
"须是 &#34;#!/bin/sh&#34;,不带引号。<br />以 # 开头的行是注释,不会执行。"
"<br />将您的自定义 mwan3 动作放在这里,他们将<br />在启用 mwan3 的接口上<br /"
">在 netifd hotplug 接口事件时执行。<br /><br />有三个主要的环境变量传递给这个"
"脚本。<br /><br />$ACTION “ifup” 或 “ifdown”<br />$INTERFACE 启动或停止的接口"
"名(例如 “wan” 或 “wwan”<br />$DEVICE 启动或停止接口的物理设备名(例如 "
"“eth0” 或 “wwan0”<br /><br />"
msgid "Tracking hostname or IP address"
msgstr "跟踪的主机或 IP 地址"
@ -421,35 +434,35 @@ msgid ""
msgstr "使用该接口的 IP 地址作为路由器本身发起的流量的源 IP 地址"
msgid "View the content of /etc/protocols for protocol description"
msgstr ""
msgstr "查看协议描述的 /etc/protocols 的内容"
msgid "WARNING: %d interfaces are configured exceeding the maximum of %d!"
msgstr "警告:已配置 %d 个接口,超过最大值 %d"
msgid "WARNING: Interface %s are not found in /etc/config/network"
msgstr ""
msgstr "警告:接口 %s 在 /etc/config/network 中未找到"
msgid "WARNING: Interface %s has a duplicate metric %s configured"
msgstr ""
msgstr "警告:接口 %s 的 metric %s 配置重复"
msgid ""
"WARNING: Interface %s has a higher reliability requirement than tracking "
"hosts (%d)"
msgstr ""
msgstr "警告:接口 %s 比跟踪主机具有更高的可靠性要求(%d"
msgid "WARNING: Interface %s has no default route in the main routing table"
msgstr ""
msgstr "警告:接口 %s 在主路由表中没有默认的路由"
msgid "WARNING: Policy %s has exceeding the maximum name of 15 characters"
msgstr ""
msgstr "警告:策略 %s 名称超过 15 个字符"
msgid ""
"WARNING: Rule %s have a port configured with no or improper protocol "
"specified!"
msgstr ""
msgstr "警告:规则 %s 有一个端口配置没有指定或协议不正确!"
msgid "Waiting for command to complete..."
msgstr ""
msgstr "正在等待命令完成..."
msgid "Weight"
msgstr "比重"

View file

@ -5,7 +5,6 @@
<%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<h2 name="content"><%:Netlink Bandwidth Monitor - Backup / Restore %></h2>

View file

@ -195,7 +195,6 @@
<%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript" src="<%=resource%>/nlbw.chart.min.js"></script>
<script type="text/javascript">//<![CDATA[

View file

@ -38,70 +38,70 @@
<fieldset class="cbi-section">
<legend><%:Recognized Clients%></legend>
<div class="cbi-section-node">
<table class="cbi-section-table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Hostname%></th>
<th class="cbi-section-table-cell"><%:IPv4%></th>
<th class="cbi-section-table-cell"><%:MAC%></th>
<th class="cbi-section-table-cell"><%:Manufacturer%></th>
<th class="cbi-section-table-cell"><%:Model%></th>
<th class="cbi-section-table-cell"><%:Class%></th>
</tr>
<div class="table cbi-section-table">
<div class="tr cbi-section-table-titles">
<div class="th cbi-section-table-cell"><%:Hostname%></div>
<div class="th cbi-section-table-cell"><%:IPv4%></div>
<div class="th cbi-section-table-cell"><%:MAC%></div>
<div class="th cbi-section-table-cell"><%:Manufacturer%></div>
<div class="th cbi-section-table-cell"><%:Model%></div>
<div class="th cbi-section-table-cell"><%:Class%></div>
</div>
<%
for i,v in ipairs(devdump) do
if v.DeviceProfileUuid ~= "" then
%>
<tr class="cbi-section-table-row cbi-rowstyle-<%=(style and 1 or 2)%>">
<td class="cbi-value-field"><%=v.Hostname%></td>
<td class="cbi-value-field"><%=v.Ipv4Address%></td>
<td class="cbi-value-field"><a href="/cgi-bin/clientdetails?mac=<%=v.MacAddress%>"><%=v.MacAddress%></a></td>
<td class="cbi-value-field"><%=devicevalues[v.DeviceProfileUuid].Manufacturer%></td>
<td class="cbi-value-field"><%=devicevalues[v.DeviceProfileUuid].Model%></td>
<td class="cbi-value-field"><%=devicevalues[v.DeviceProfileUuid].ThingClass%></td>
</tr>
<div class="tr cbi-section-table-row cbi-rowstyle-<%=(style and 1 or 2)%>">
<div class="td cbi-value-field"><%=v.Hostname%></div>
<div class="td cbi-value-field"><%=v.Ipv4Address%></div>
<div class="td cbi-value-field"><a href="/cgi-bin/clientdetails?mac=<%=v.MacAddress%>"><%=v.MacAddress%></a></div>
<div class="td cbi-value-field"><%=devicevalues[v.DeviceProfileUuid].Manufacturer%></div>
<div class="td cbi-value-field"><%=devicevalues[v.DeviceProfileUuid].Model%></div>
<div class="td cbi-value-field"><%=devicevalues[v.DeviceProfileUuid].ThingClass%></div>
</div>
<%
style=false
end
end
%>
</table>
</div>
</div>
</fieldset>
<br />
<fieldset class="cbi-section">
<legend><%:Unrecognized Clients%></legend>
<div class="cbi-section-node">
<table class="cbi-section-table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Hostname%></th>
<th class="cbi-section-table-cell"><%:IPv4%></th>
<th class="cbi-section-table-cell"><%:MAC%></th>
<th class="cbi-section-table-cell"><%:Manufacturer%></th>
<th class="cbi-section-table-cell"><%:Model%></th>
<th class="cbi-section-table-cell"><%:DhcpVendor%></th>
<th class="cbi-section-table-cell"><%:DhcpHostname%></th>
</tr>
<div class="table cbi-section-table">
<div class="tr cbi-section-table-titles">
<div class="th cbi-section-table-cell"><%:Hostname%></div>
<div class="th cbi-section-table-cell"><%:IPv4%></div>
<div class="th cbi-section-table-cell"><%:MAC%></div>
<div class="th cbi-section-table-cell"><%:Manufacturer%></div>
<div class="th cbi-section-table-cell"><%:Model%></div>
<div class="th cbi-section-table-cell"><%:DhcpVendor%></div>
<div class="th cbi-section-table-cell"><%:DhcpHostname%></div>
</div>
<%
for i,v in ipairs(devdump) do
if v.DeviceProfileUuid == "" then
%>
<tr class="cbi-section-table-row cbi-rowstyle-<%=(style and 1 or 2)%>">
<td class="cbi-value-field"><%=v.Hostname%></td>
<td class="cbi-value-field"><%=v.Ipv4Address%></td>
<td class="cbi-value-field"><a href="/cgi-bin/clientdetails?mac=<%=v.MacAddress%>"><%=v.MacAddress%></a></td>
<td class="cbi-value-field"><%=v.SsdpManufacturer%></td>
<td class="cbi-value-field"><%=v.SsdpModelName%></td>
<td class="cbi-value-field"><%=v.DhcpVendor1%></td>
<td class="cbi-value-field"><%=v.DhcpHostname%></td>
</tr>
<div class="tr cbi-section-table-row cbi-rowstyle-<%=(style and 1 or 2)%>">
<div class="td cbi-value-field"><%=v.Hostname%></div>
<div class="td cbi-value-field"><%=v.Ipv4Address%></div>
<div class="td cbi-value-field"><a href="/cgi-bin/clientdetails?mac=<%=v.MacAddress%>"><%=v.MacAddress%></a></div>
<div class="td cbi-value-field"><%=v.SsdpManufacturer%></div>
<div class="td cbi-value-field"><%=v.SsdpModelName%></div>
<div class="td cbi-value-field"><%=v.DhcpVendor1%></div>
<div class="td cbi-value-field"><%=v.DhcpHostname%></div>
</div>
<%
style=false
end
end
%>
</table>
</div>
</div>
</fieldset>

View file

@ -5,8 +5,8 @@
function(x)
{
var tb = document.getElementById('ocserv_status_table');
if (tb && (idx < tb.rows.length))
tb.rows[0].parentNode.removeChild(tb.rows[idx]);
if (tb && (idx + 1 < tb.childNodes.length))
tb.removeChild(tb.childNodes[idx + 1]);
}
);
}
@ -18,38 +18,28 @@
if (st && tb)
{
/* clear all rows */
while( tb.rows.length > 1 )
tb.deleteRow(1);
while (tb.firstElementChild !== tb.lastElementChild)
tb.removeChild(tb.lastElementChild);
for( var i = 0; i < st.length; i++ )
for (var i = 0; i < st.length; i++)
{
var tr = tb.insertRow(-1);
tr.className = 'cbi-section-table-row cbi-rowstyle-' + ((i % 2) + 1);
tr.insertCell(-1).innerHTML = st[i].user;
tr.insertCell(-1).innerHTML = st[i].group;
tr.insertCell(-1).innerHTML = st[i].vpn_ip;
tr.insertCell(-1).innerHTML = st[i].ip;
tr.insertCell(-1).innerHTML = st[i].device;
tr.insertCell(-1).innerHTML = st[i].time;
tr.insertCell(-1).innerHTML = st[i].cipher;
tr.insertCell(-1).innerHTML = st[i].status;
tr.insertCell(-1).innerHTML = String.format(
'<input class="cbi-button cbi-input-remove" type="button" value="<%:Disconnect%>" onclick="ocserv_disconnect(%d)" />',
st[i].id
);
tb.appendChild(E('<div class="tr cbi-section-table-row cbi-rowstyle-%d">'.format((i % 2) + 1), [
E('<div class="td">', st[i].user),
E('<div class="td">', st[i].group),
E('<div class="td">', st[i].vpn_ip),
E('<div class="td">', st[i].ip),
E('<div class="td">', st[i].device),
E('<div class="td">', st[i].time),
E('<div class="td">', st[i].cipher),
E('<div class="td">', st[i].status),
E('<div class="td">',
E('<input class="cbi-button cbi-input-remove" type="button" value="<%:Disconnect%>" onclick="ocserv_disconnect(%d)" />'
.format(st[i].id)))
]));
}
if( tb.rows.length == 1 )
{
var tr = tb.insertRow(-1);
tr.className = 'cbi-section-table-row';
var td = tr.insertCell(-1);
td.colSpan = 5;
td.innerHTML = '<em><br /><%:There are no active users.%></em>';
}
if (tb.firstElementChild === tb.lastElementChild)
tb.appendChild(E('<div class="tr cbi-section-table-row"><div class="td"><em><br /><%:There are no active users.%></em></div></div>'));
}
}
);
@ -57,20 +47,21 @@
<fieldset class="cbi-section">
<legend><%:Active OpenConnect Users%></legend>
<table class="cbi-section-table" id="ocserv_status_table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:User%></th>
<th class="cbi-section-table-cell"><%:Group%></th>
<th class="cbi-section-table-cell"><%:IP Address%></th>
<th class="cbi-section-table-cell"><%:VPN IP Address%></th>
<th class="cbi-section-table-cell"><%:Device%></th>
<th class="cbi-section-table-cell"><%:Time%></th>
<th class="cbi-section-table-cell"><%:Cipher%></th>
<th class="cbi-section-table-cell"><%:Status%></th>
<th class="cbi-section-table-cell">&#160;</th>
</tr>
<tr class="cbi-section-table-row">
<td colspan="5"><em><br /><%:Collecting data...%></em></td>
</tr>
</table>
<div class="table cbi-section-table" id="ocserv_status_table">
<div class="tr cbi-section-table-titles">
<div class="th cbi-section-table-cell"><%:User%></div>
<div class="th cbi-section-table-cell"><%:Group%></div>
<div class="th cbi-section-table-cell"><%:IP Address%></div>
<div class="th cbi-section-table-cell"><%:VPN IP Address%></div>
<div class="th cbi-section-table-cell"><%:Device%></div>
<div class="th cbi-section-table-cell"><%:Time%></div>
<div class="th cbi-section-table-cell"><%:Cipher%></div>
<div class="th cbi-section-table-cell"><%:Status%></div>
<div class="th cbi-section-table-cell">&#160;</div>
</div>
<div class="tr cbi-section-table-row">
<div class="td" colspan="5"><em><br /><%:Collecting data...%></em></div>
</div>
</div>
</fieldset>

View file

@ -118,7 +118,6 @@ end
<%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript">//<![CDATA[
XHR.poll(10 , '<%=REQUEST_URI%>', { status: 1 },
@ -132,11 +131,11 @@ end
{
var service = info[idx];
s += String.format(
'<tr class="cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+'">' +
'<td class="cbi-section-table-titles"><a href="%s">%s</a></td>' +
'<td class="cbi-section-table-titles">%s</td>' +
'<td class="cbi-section-table-titles"><a href="http://%s/cgi-bin-status.html">%s</a></td>' +
'</tr>',
'<div class="tr cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+'">' +
'<div class="td cbi-section-table-titles"><a href="%s">%s</a></div>' +
'<div class="td cbi-section-table-titles">%s</div>' +
'<div class="td cbi-section-table-titles"><a href="http://%s/cgi-bin-status.html">%s</a></div>' +
'</div>',
service.url, service.descr, service.proto, service.origin_link, service.origin || '?'
);
}
@ -153,16 +152,16 @@ end
<fieldset class="cbi-section">
<legend><%:Internal services%></legend>
<table class="cbi-section-table">
<thead>
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Url%></th>
<th class="cbi-section-table-cell"><%:Protocol%></th>
<th class="cbi-section-table-cell"><%:Source%></th>
</tr>
</thead>
<div class="table cbi-section-table">
<div class="thead">
<div class="tr cbi-section-table-titles">
<div class="th cbi-section-table-cell"><%:Url%></div>
<div class="th cbi-section-table-cell"><%:Protocol%></div>
<div class="th cbi-section-table-cell"><%:Source%></div>
</div>
</div>
<tbody id="olsr_services">
<div class="tbody" id="olsr_services">
<%
for k, line in ipairs(services) do
local field = {}
@ -178,15 +177,15 @@ end
local url, proto, descr, origin = pcdata(field[1]), pcdata(field[2]), utl.trim(pcdata(field[3])), pcdata(field[4])
%>
<tr class="cbi-section-table-row cbi-rowstyle-<%=i%>">
<td class="cbi-section-table-titles"><a href="<%=url%>"><%=descr%></a></td>
<td class="cbi-section-table-titles"><%=proto%></td>
<td class="cbi-section-table-titles"><a href="http://<%=origin_link%>/cgi-bin-status.html"><%=origin%></a></td>
</tr>
<div class="tr cbi-section-table-row cbi-rowstyle-<%=i%>">
<div class="td cbi-section-table-titles"><a href="<%=url%>"><%=descr%></a></div>
<div class="td cbi-section-table-titles"><%=proto%></div>
<div class="td cbi-section-table-titles"><a href="http://<%=origin_link%>/cgi-bin-status.html"><%=origin%></a></div>
</div>
<% i = ((i % 2) + 1)
end %>
</tbody>
</table>
</div>
</div>
<br />
<%=last_update%>
</fieldset>

View file

@ -11,7 +11,7 @@ cat<<EOF
</HEAD>
<BODY>
<script langauge='JavaScript1.2' type='text/javascript'>
<script language='JavaScript1.2' type='text/javascript'>
EOF
# sed + txtinfo plugin

View file

@ -28,7 +28,6 @@ end
<%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript">//<![CDATA[
XHR.poll(10, '<%=REQUEST_URI%>', { status: 1 },
function(x, info)
@ -41,7 +40,7 @@ XHR.poll(10, '<%=REQUEST_URI%>', { status: 1 },
{
var hna = info[idx];
var linkgw = ''
s += '<tr class="cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+' proto-' + hna.proto + '">'
s += '<div class="tr cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+' proto-' + hna.proto + '">'
if (hna.proto == '6') {
linkgw = '<a href="http://[' + hna.gateway + ']/cgi-bin-status.html">' + hna.gateway + '</a>'
} else {
@ -61,11 +60,11 @@ XHR.poll(10, '<%=REQUEST_URI%>', { status: 1 },
}
s += String.format(
'<td class="cbi-section-table-cell">%s</td>' +
'<td class="cbi-section-table-cell">%s</td>' +
'<td class="cbi-section-table-cell">%s</td>', hna.destination + '/' + hna.genmask, linkgw + hostname, validity
'<div class="td cbi-section-table-cell">%s</div>' +
'<div class="td cbi-section-table-cell">%s</div>' +
'<div class="td cbi-section-table-cell">%s</div>', hna.destination + '/' + hna.genmask, linkgw + hostname, validity
)
s += '</tr>'
s += '</div>'
}
hnadiv.innerHTML = s;
}
@ -79,21 +78,21 @@ XHR.poll(10, '<%=REQUEST_URI%>', { status: 1 },
<fieldset class="cbi-section">
<legend><%:Overview of currently active OLSR host net announcements%></legend>
<table class="cbi-section-table">
<thead>
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Announced network%></th>
<th class="cbi-section-table-cell"><%:OLSR gateway%></th>
<th class="cbi-section-table-cell"><%:Validity Time%></th>
</tr>
<div class="table cbi-section-table">
<div class="thead">
<div class="tr cbi-section-table-titles">
<div class="th cbi-section-table-cell"><%:Announced network%></div>
<div class="th cbi-section-table-cell"><%:OLSR gateway%></div>
<div class="th cbi-section-table-cell"><%:Validity Time%></div>
</div>
</thead>
<tbody id="olsrd_hna">
</div>
<div class="tbody" id="olsrd_hna">
<% for k, route in ipairs(hna) do %>
<tr class="cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=hna[k].proto%>">
<td class="cbi-section-table-cell"><%=hna[k].destination%>/<%=hna[k].genmask%> </td>
<td class="cbi-section-table-cell">
<div class="tr cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=hna[k].proto%>">
<div class="td cbi-section-table-cell"><%=hna[k].destination%>/<%=hna[k].genmask%> </div>
<div class="td cbi-section-table-cell">
<% if hna[k].proto == '6' then %>
<a href="http://[<%=hna[k].gateway%>]/cgi-bin-status.html"><%=hna[k].gateway%></a>
<% else %>
@ -102,20 +101,20 @@ XHR.poll(10, '<%=REQUEST_URI%>', { status: 1 },
<% if hna[k].hostname then %>
/ <a href="http://<%=hna[k].hostname%>/cgi-bin-status.html"><%=hna[k].hostname%></a>
<% end %>
</td>
</div>
<% if hna[k].validityTime then
validity = hna[k].validityTime .. 's'
else
validity = '-'
end %>
<td class="cbi-section-table-cell"><%=validity%></td>
</tr>
<div class="td cbi-section-table-cell"><%=validity%></div>
</div>
<% i = ((i % 2) + 1)
end %>
</tbody>
</table>
</div>
</div>
</fieldset>
<%+status-olsr/common_js%>

View file

@ -18,31 +18,31 @@ local i = 1
<fieldset class="cbi-section">
<legend><%:Overview of interfaces where OLSR is running%></legend>
<table class="cbi-section-table">
<tr>
<th class="cbi-section-table-cell"><%:Interface%></th>
<th class="cbi-section-table-cell"><%:State%></th>
<th class="cbi-section-table-cell"><%:MTU%></th>
<th class="cbi-section-table-cell"><%:WLAN%></th>
<th class="cbi-section-table-cell"><%:Source address%></th>
<th class="cbi-section-table-cell"><%:Netmask%></th>
<th class="cbi-section-table-cell"><%:Broadcast address%></th>
</tr>
<div class="table cbi-section-table">
<div class="tr">
<div class="th cbi-section-table-cell"><%:Interface%></div>
<div class="th cbi-section-table-cell"><%:State%></div>
<div class="th cbi-section-table-cell"><%:MTU%></div>
<div class="th cbi-section-table-cell"><%:WLAN%></div>
<div class="th cbi-section-table-cell"><%:Source address%></div>
<div class="th cbi-section-table-cell"><%:Netmask%></div>
<div class="th cbi-section-table-cell"><%:Broadcast address%></div>
</div>
<% for k, iface in ipairs(iface) do %>
<tr class="cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=iface.proto%>">
<td class="cbi-section-table-cell"><%=iface.name%></td>
<td class="cbi-section-table-cell"><%=iface.state%></td>
<td class="cbi-section-table-cell"><%=iface.olsrMTU%></td>
<td class="cbi-section-table-cell"><%=iface.wireless and luci.i18n.translate('yes') or luci.i18n.translate('no')%></td>
<td class="cbi-section-table-cell"><%=iface.ipv4Address or iface.ipv6Address%></td>
<td class="cbi-section-table-cell"><%=iface.netmask%></td>
<td class="cbi-section-table-cell"><%=iface.broadcast or iface.multicast%></td>
</tr>
<div class="tr cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=iface.proto%>">
<div class="td cbi-section-table-cell"><%=iface.name%></div>
<div class="td cbi-section-table-cell"><%=iface.state%></div>
<div class="td cbi-section-table-cell"><%=iface.olsrMTU%></div>
<div class="td cbi-section-table-cell"><%=iface.wireless and luci.i18n.translate('yes') or luci.i18n.translate('no')%></div>
<div class="td cbi-section-table-cell"><%=iface.ipv4Address or iface.ipv6Address%></div>
<div class="td cbi-section-table-cell"><%=iface.netmask%></div>
<div class="td cbi-section-table-cell"><%=iface.broadcast or iface.multicast%></div>
</div>
<% i = ((i % 2) + 1)
end %>
</table>
</div>
</fieldset>
<%+status-olsr/common_js%>
<%+footer%>

View file

@ -15,11 +15,11 @@ local i = 1
<div id="togglebuttons"></div>
<fieldset class="cbi-section">
<legend><%:Overview of known multiple interface announcements%></legend>
<table class="cbi-section-table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:OLSR node%></th>
<th class="cbi-section-table-cell" ><%:Secondary OLSR interfaces%></th>
</tr>
<div class="table cbi-section-table">
<div class="tr cbi-section-table-titles">
<div class="th cbi-section-table-cell"><%:OLSR node%></div>
<div class="th cbi-section-table-cell" ><%:Secondary OLSR interfaces%></div>
</div>
<% for k, mid in ipairs(mids) do
local aliases = ''
@ -37,14 +37,14 @@ local i = 1
end
%>
<tr class="cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=mid.proto%>">
<td class="cbi-section-table-cell"><a href="http://<%=host%>/cgi-bin-status.html"><%=mid.ipAddress%></a></td>
<td class="cbi-section-table-cell"><%=aliases%></td>
</tr>
<div class="tr cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=mid.proto%>">
<div class="td cbi-section-table-cell"><a href="http://<%=host%>/cgi-bin-status.html"><%=mid.ipAddress%></a></div>
<div class="td cbi-section-table-cell"><%=aliases%></div>
</div>
<% i = ((i % 2) + 1)
end %>
</table>
</div>
</fieldset>
<%+status-olsr/common_js%>
<%+footer%>

View file

@ -48,7 +48,6 @@ end
<%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript">//<![CDATA[
XHR.poll(10 , '<%=REQUEST_URI%>', { status: 1 },
@ -64,36 +63,36 @@ end
if (neigh.proto == '6') {
s += String.format(
'<tr class="cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+' proto-%s">' +
'<td class="cbi-section-table-titles" style="background-color:%s"><a href="http://[%s]/cgi-bin-status.html">%s</a></td>',
'<div class="tr cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+' proto-%s">' +
'<div class="td cbi-section-table-titles" style="background-color:%s"><a href="http://[%s]/cgi-bin-status.html">%s</a></div>',
neigh.proto, neigh.dfgcolor, neigh.rip, neigh.rip
);
} else {
s += String.format(
'<tr class="cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+' proto-%s">' +
'<td class="cbi-section-table-titles" style="background-color:%s"><a href="http://%s/cgi-bin-status.html">%s</a></td>',
'<div class="tr cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+' proto-%s">' +
'<div class="td cbi-section-table-titles" style="background-color:%s"><a href="http://%s/cgi-bin-status.html">%s</a></div>',
neigh.proto, neigh.dfgcolor, neigh.rip, neigh.rip
);
}
if (neigh.hn) {
s += String.format(
'<td class="cbi-section-table-titles" style="background-color:%s"><a href="http://%s/cgi-bin-status.html">%s</a></td>',
'<div class="td cbi-section-table-titles" style="background-color:%s"><a href="http://%s/cgi-bin-status.html">%s</a></div>',
neigh.dfgcolor, neigh.hn, neigh.hn
);
} else {
s += String.format(
'<td class="cbi-section-table-titles" style="background-color:%s">?</td>',
'<div class="td cbi-section-table-titles" style="background-color:%s">?</div>',
neigh.dfgcolor
);
}
s += String.format(
'<td class="cbi-section-table-titles" style="background-color:%s">%s</td>' +
'<td class="cbi-section-table-titles" style="background-color:%s">%s</td>' +
'<td class="cbi-section-table-titles" style="background-color:%s">%s</td>' +
'<td class="cbi-section-table-titles" style="background-color:%s">%s</td>' +
'<td class="cbi-section-table-titles" style="background-color:%s">%s</td>' +
'<td class="cbi-section-table-titles" style="background-color:%s" title="Signal: %s Noise: %s">%s</td>' +
'</tr>',
'<div class="td cbi-section-table-titles" style="background-color:%s">%s</div>' +
'<div class="td cbi-section-table-titles" style="background-color:%s">%s</div>' +
'<div class="td cbi-section-table-titles" style="background-color:%s">%s</div>' +
'<div class="td cbi-section-table-titles" style="background-color:%s">%s</div>' +
'<div class="td cbi-section-table-titles" style="background-color:%s">%s</div>' +
'<div class="td cbi-section-table-titles" style="background-color:%s" title="Signal: %s Noise: %s">%s</div>' +
'</div>',
neigh.dfgcolor, neigh.ifn, neigh.dfgcolor, neigh.lip, neigh.dfgcolor, neigh.lq, neigh.dfgcolor, neigh.nlq, neigh.color, neigh.cost, neigh.snr_color, neigh.signal, neigh.noise, neigh.snr || '?'
);
}
@ -112,21 +111,21 @@ end
<fieldset class="cbi-section">
<legend><%:Overview of currently established OLSR connections%></legend>
<table class="cbi-section-table">
<thead>
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Neighbour IP%></th>
<th class="cbi-section-table-cell"><%:Hostname%></th>
<th class="cbi-section-table-cell"><%:Interface%></th>
<th class="cbi-section-table-cell"><%:Local interface IP%></th>
<th class="cbi-section-table-cell">LQ</th>
<th class="cbi-section-table-cell">NLQ</th>
<th class="cbi-section-table-cell">ETX</th>
<th class="cbi-section-table-cell">SNR</th>
</tr>
</thead>
<div class="table cbi-section-table">
<div class="thead">
<div class="tr cbi-section-table-titles">
<div class="th cbi-section-table-cell"><%:Neighbour IP%></div>
<div class="th cbi-section-table-cell"><%:Hostname%></div>
<div class="th cbi-section-table-cell"><%:Interface%></div>
<div class="th cbi-section-table-cell"><%:Local interface IP%></div>
<div class="th cbi-section-table-cell">LQ</div>
<div class="th cbi-section-table-cell">NLQ</div>
<div class="th cbi-section-table-cell">ETX</div>
<div class="th cbi-section-table-cell">SNR</div>
</div>
</div>
<tbody id="olsr_neigh_table">
<div class="tbody" id="olsr_neigh_table">
<% local i = 1
for k, link in ipairs(links) do
link.linkCost = tonumber(link.linkCost) or 0
@ -147,25 +146,25 @@ end
end
%>
<tr class="cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=link.proto%>">
<div class="tr cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=link.proto%>">
<% if link.proto == "6" then %>
<td class="cbi-section-table-titles" style="background-color:<%=defaultgw_color%>"><a href="http://[<%=link.remoteIP%>]/cgi-bin-status.html"><%=link.remoteIP%></a></td>
<div class="td cbi-section-table-titles" style="background-color:<%=defaultgw_color%>"><a href="http://[<%=link.remoteIP%>]/cgi-bin-status.html"><%=link.remoteIP%></a></div>
<% else %>
<td class="cbi-section-table-titles" style="background-color:<%=defaultgw_color%>"><a href="http://<%=link.remoteIP%>/cgi-bin-status.html"><%=link.remoteIP%></a></td>
<div class="td cbi-section-table-titles" style="background-color:<%=defaultgw_color%>"><a href="http://<%=link.remoteIP%>/cgi-bin-status.html"><%=link.remoteIP%></a></div>
<% end %>
<td class="cbi-section-table-titles" style="background-color:<%=defaultgw_color%>"><a href="http://<%=link.hostname%>/cgi-bin-status.html"><%=link.hostname%></a></td>
<td class="cbi-section-table-titles" style="background-color:<%=defaultgw_color%>"><%=link.interface%></td>
<td class="cbi-section-table-titles" style="background-color:<%=defaultgw_color%>"><%=link.localIP%></td>
<td class="cbi-section-table-titles" style="background-color:<%=defaultgw_color%>"><%=string.format("%.3f", link.linkQuality)%></td>
<td class="cbi-section-table-titles" style="background-color:<%=defaultgw_color%>"><%=string.format("%.3f", link.neighborLinkQuality)%></td>
<td class="cbi-section-table-titles" style="background-color:<%=color%>"><%=string.format("%.3f", link.linkCost)%></td>
<td class="cbi-section-table-titles" style="background-color:<%=snr_color%>" title="Signal: <%=link.signal%> Noise: <%=link.noise%>"><%=link.snr%></td>
</tr>
<div class="td cbi-section-table-titles" style="background-color:<%=defaultgw_color%>"><a href="http://<%=link.hostname%>/cgi-bin-status.html"><%=link.hostname%></a></div>
<div class="td cbi-section-table-titles" style="background-color:<%=defaultgw_color%>"><%=link.interface%></div>
<div class="td cbi-section-table-titles" style="background-color:<%=defaultgw_color%>"><%=link.localIP%></div>
<div class="td cbi-section-table-titles" style="background-color:<%=defaultgw_color%>"><%=string.format("%.3f", link.linkQuality)%></div>
<div class="td cbi-section-table-titles" style="background-color:<%=defaultgw_color%>"><%=string.format("%.3f", link.neighborLinkQuality)%></div>
<div class="td cbi-section-table-titles" style="background-color:<%=color%>"><%=string.format("%.3f", link.linkCost)%></div>
<div class="td cbi-section-table-titles" style="background-color:<%=snr_color%>" title="Signal: <%=link.signal%> Noise: <%=link.noise%>"><%=link.snr%></div>
</div>
<%
i = ((i % 2) + 1)
end %>
</tbody>
</table>
</div>
</div>
<br />
<%+status-olsr/legend%>

View file

@ -45,7 +45,6 @@ end
<%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript">//<![CDATA[
XHR.poll(10, '<%=REQUEST_URI%>/json', { },
@ -160,48 +159,48 @@ XHR.poll(10, '<%=REQUEST_URI%>/json', { },
<fieldset class="cbi-section">
<legend><%:Network%></legend>
<table width="100%" cellspacing="10">
<tr><td width="33%"><%:Interfaces%></td><td>
<div class="table" width="100%" cellspacing="10">
<div class="tr"><div class="td" width="33%"><%:Interfaces%></div><div class="td">
<a href="<%=REQUEST_URI%>/interfaces">
<span id="nr_ifaces">-<span>
</a>
</td></tr>
<tr><td width="33%"><%:Neighbors%></td><td>
</div></div>
<div class="tr"><div class="td" width="33%"><%:Neighbors%></div><div class="td">
<a href="<%=REQUEST_URI%>/neighbors">
<span id="nr_neigh">-</span>
</a>
</td></tr>
<tr><td width="33%"><%:Nodes%></td><td>
</div></div>
<div class="tr"><div class="td" width="33%"><%:Nodes%></div><div class="td">
<a href="<%=REQUEST_URI%>/topology">
<span id="nr_nodes">-</span>
</a>
</td></tr>
<tr><td width="33%"><%:HNA%></td><td>
</div></div>
<div class="tr"><div class="td" width="33%"><%:HNA%></div><div class="td">
<a href="<%=REQUEST_URI%>/hna">
<span id="nr_hna">-</span>
</a>
</td></tr>
<tr><td width="33%"><%:Links total%></td><td>
</div></div>
<div class="tr"><div class="td" width="33%"><%:Links total%></div><div class="td">
<a href="<%=REQUEST_URI%>/topology">
<span id="nr_topo">-</span>
</a>
</td></tr>
<tr><td width="33%"><%:Links per node (average)%></td><td>
</div></div>
<div class="tr"><div class="td" width="33%"><%:Links per node (average)%></div><div class="td">
<span id="meshfactor">-</span>
</td></tr>
</div></div>
</table>
</div>
</fieldset>
<fieldset class="cbi-section">
<legend>OLSR <%:Configuration%></legend>
<table width="100%" cellspacing="10">
<tr><td width="33%"><%:Version%></td><td>
<div class="table" width="100%" cellspacing="10">
<div class="tr"><div class="td" width="33%"><%:Version%></div><div class="td">
<span id="version">-<span>
</td></tr>
<tr><td width="33%"><%:Download Config%></td><td>
</div></div>
<div class="tr"><div class="td" width="33%"><%:Download Config%></div><div class="td">
<% if has_ipv4_conf then %>
<a href="<%=REQUEST_URI%>?openwrt_v4">OpenWrt (IPv4)</a>,
<% end %>
@ -214,8 +213,8 @@ XHR.poll(10, '<%=REQUEST_URI%>/json', { },
<% if has_ipv6_conf then %>
<a href="<%=REQUEST_URI%>?conf_v6">OLSRD (IPv6)</a>
<% end %>
</td></tr>
</table>
</div></div>
</div>
</fieldset>
<%+footer%>

View file

@ -34,7 +34,6 @@ end
<%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript">//<![CDATA[
XHR.poll(20, '<%=REQUEST_URI%>', { status: 1 },
@ -50,9 +49,9 @@ XHR.poll(20, '<%=REQUEST_URI%>', { status: 1 },
var route = info[idx];
s += String.format(
'<tr class="cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+' proto-%s">' +
'<td class="cbi-section-table-cell">%s/%s</td>' +
'<td class="cbi-section-table-cell">' +
'<div class="tr cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+' proto-%s">' +
'<div class="td cbi-section-table-cell">%s/%s</div>' +
'<div class="td cbi-section-table-cell">' +
'<a href="http://%s/cgi-bin-status.html">%s</a>',
route.proto, route.dest, route.genmask, route.gw, route.gw
)
@ -72,11 +71,11 @@ XHR.poll(20, '<%=REQUEST_URI%>', { status: 1 },
}
s += String.format(
'</td>' +
'<td class="cbi-section-table-cell">%s</td>' +
'<td class="cbi-section-table-cell">%s</td>' +
'<td class="cbi-section-table-cell" style="background-color:%s">%s</td>' +
'</tr>',
'</div>' +
'<div class="td cbi-section-table-cell">%s</div>' +
'<div class="td cbi-section-table-cell">%s</div>' +
'<div class="td cbi-section-table-cell" style="background-color:%s">%s</div>' +
'</div>',
route.interface, route.metric, route.color, route.etx || '?'
);
}
@ -96,27 +95,27 @@ XHR.poll(20, '<%=REQUEST_URI%>', { status: 1 },
<fieldset class="cbi-section">
<legend><%:Overview of currently known routes to other OLSR nodes%></legend>
<table class="cbi-section-table">
<thead>
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Announced network%></th>
<th class="cbi-section-table-cell"><%:OLSR gateway%></th>
<th class="cbi-section-table-cell"><%:Interface%></th>
<th class="cbi-section-table-cell"><%:Metric%></th>
<th class="cbi-section-table-cell">ETX</th>
</tr>
</thead>
<div class="table cbi-section-table">
<div class="thead">
<div class="tr cbi-section-table-titles">
<div class="th cbi-section-table-cell"><%:Announced network%></div>
<div class="th cbi-section-table-cell"><%:OLSR gateway%></div>
<div class="th cbi-section-table-cell"><%:Interface%></div>
<div class="th cbi-section-table-cell"><%:Metric%></div>
<div class="th cbi-section-table-cell">ETX</div>
</div>
</div>
<tbody id="olsrd_routes">
<div class="tbody" id="olsrd_routes">
<% for k, route in ipairs(routes) do
ETX = tonumber(route.rtpMetricCost)/1024 or '0'
color = olsrtools.etx_color(ETX)
%>
<tr class="cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=route.proto%>">
<td class="cbi-section-table-cell"><%=route.destination%>/<%=route.genmask%></td>
<td class="cbi-section-table-cell">
<div class="tr cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=route.proto%>">
<div class="td cbi-section-table-cell"><%=route.destination%>/<%=route.genmask%></div>
<div class="td cbi-section-table-cell">
<% if route.proto == '6' then %>
<a href="http://[<%=route.gateway%>]/cgi-bin-status.html"><%=route.gateway%></a>
<% else %>
@ -125,16 +124,16 @@ XHR.poll(20, '<%=REQUEST_URI%>', { status: 1 },
<% if route.hostname then %>
/ <a href="http://<%=route.Hostname%>/cgi-bin-status.html"><%=route.hostname%></a>
<% end %>
</td>
<td class="cbi-section-table-cell"><%=route.networkInterface%></td>
<td class="cbi-section-table-cell"><%=route.metric%></td>
<td class="cbi-section-table-cell" style="background-color:<%=color%>"><%=string.format("%.3f", ETX)%></td>
</tr>
</div>
<div class="td cbi-section-table-cell"><%=route.networkInterface%></div>
<div class="td cbi-section-table-cell"><%=route.metric%></div>
<div class="td cbi-section-table-cell" style="background-color:<%=color%>"><%=string.format("%.3f", ETX)%></div>
</div>
<%
i = ((i % 2) + 1)
end %>
</tbody>
</table>
</div>
</div>
<%+status-olsr/legend%>
</fieldset>

View file

@ -44,7 +44,6 @@ end
<%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript">//<![CDATA[
XHR.poll(10, '<%=REQUEST_URI%>', { status: 1 },
function(x, info)
@ -56,7 +55,7 @@ XHR.poll(10, '<%=REQUEST_URI%>', { status: 1 },
for (var idx = 0; idx < info.length; idx++)
{
var smartgw = info[idx];
s += '<tr class="cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+' proto-' + smartgw.proto + '">'
s += '<div class="tr cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+' proto-' + smartgw.proto + '">'
if (smartgw.proto == '6') {
linkgw = '<a href="http://[' + smartgw.ipAddress + ']/cgi-bin-status.html">' + smartgw.ipAddress + '</a>'
} else {
@ -64,18 +63,18 @@ XHR.poll(10, '<%=REQUEST_URI%>', { status: 1 },
}
s += String.format(
'<td class="cbi-section-table-cell">%s</td>' +
'<td class="cbi-section-table-cell">%s</td>' +
'<td class="cbi-section-table-cell">%s</td>' +
'<td class="cbi-section-table-cell">%s</td>' +
'<td class="cbi-section-table-cell">%s</td>' +
'<td class="cbi-section-table-cell">%s</td>' +
'<td class="cbi-section-table-cell">%s</td>' +
'<td class="cbi-section-table-cell">%s</td>' +
'<td class="cbi-section-table-cell">%s</td>',
'<div class="td cbi-section-table-cell">%s</div>' +
'<div class="td cbi-section-table-cell">%s</div>' +
'<div class="td cbi-section-table-cell">%s</div>' +
'<div class="td cbi-section-table-cell">%s</div>' +
'<div class="td cbi-section-table-cell">%s</div>' +
'<div class="td cbi-section-table-cell">%s</div>' +
'<div class="td cbi-section-table-cell">%s</div>' +
'<div class="td cbi-section-table-cell">%s</div>' +
'<div class="td cbi-section-table-cell">%s</div>',
linkgw, smartgw.status, smartgw.tcPathCost, smartgw.hopCount, smartgw.uplinkSpeed, smartgw.downlinkSpeed, smartgw.v4, smartgw.v6, smartgw.externalPrefix
)
s += '</tr>'
s += '</div>'
}
smartgwdiv.innerHTML = s;
}
@ -94,23 +93,23 @@ XHR.poll(10, '<%=REQUEST_URI%>', { status: 1 },
<fieldset class="cbi-section">
<legend><%:Overview of smart gateways in this network%></legend>
<table class="cbi-section-table">
<thead>
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Gateway%></th>
<th class="cbi-section-table-cell"><%:Status%></th>
<th class="cbi-section-table-cell"><%:ETX%></th>
<th class="cbi-section-table-cell"><%:Hops%></th>
<th class="cbi-section-table-cell"><%:Uplink%></th>
<th class="cbi-section-table-cell"><%:Downlink%></th>
<th class="cbi-section-table-cell"><%:IPv4%></th>
<th class="cbi-section-table-cell"><%:IPv6%></th>
<th class="cbi-section-table-cell"><%:Prefix%></th>
<div class="table cbi-section-table">
<div class="thead">
<div class="tr cbi-section-table-titles">
<div class="th cbi-section-table-cell"><%:Gateway%></div>
<div class="th cbi-section-table-cell"><%:Status%></div>
<div class="th cbi-section-table-cell"><%:ETX%></div>
<div class="th cbi-section-table-cell"><%:Hops%></div>
<div class="th cbi-section-table-cell"><%:Uplink%></div>
<div class="th cbi-section-table-cell"><%:Downlink%></div>
<div class="th cbi-section-table-cell"><%:IPv4%></div>
<div class="th cbi-section-table-cell"><%:IPv6%></div>
<div class="th cbi-section-table-cell"><%:Prefix%></div>
</tr>
</thead>
</div>
</div>
<tbody id="olsrd_smartgw">
<div class="tbody" id="olsrd_smartgw">
<% for k, gw in ipairs(gws) do
gw.tcPathCost = tonumber(gw.tcPathCost)/1024 or 0
@ -119,27 +118,27 @@ XHR.poll(10, '<%=REQUEST_URI%>', { status: 1 },
end
%>
<tr class="cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=proto%>">
<div class="tr cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=proto%>">
<% if gw.proto == '6' then %>
<td class="cbi-section-table-cell"><a href="http://[<%=gw.ipAddress%>]/cgi-bin-status.html"><%=gw.ipAddress%></a></td>
<div class="td cbi-section-table-cell"><a href="http://[<%=gw.ipAddress%>]/cgi-bin-status.html"><%=gw.ipAddress%></a></div>
<% else %>
<td class="cbi-section-table-cell"><a href="http://<%=gw.ipAddress%>/cgi-bin-status.html"><%=gw.ipAddress%></a></td>
<div class="td cbi-section-table-cell"><a href="http://<%=gw.ipAddress%>/cgi-bin-status.html"><%=gw.ipAddress%></a></div>
<% end %>
<td class="cbi-section-table-cell"><%=gw.ipv4Status or gw.ipv6Status or '-' %></td>
<td class="cbi-section-table-cell"><%=string.format("%.3f", gw.tcPathCost)%></td>
<td class="cbi-section-table-cell"><%=gw.hopCount%></td>
<td class="cbi-section-table-cell"><%=gw.uplinkSpeed%></td>
<td class="cbi-section-table-cell"><%=gw.downlinkSpeed%></td>
<td class="cbi-section-table-cell"><%=gw.ipv4 and luci.i18n.translate('yes') or luci.i18n.translate('no')%></td>
<td class="cbi-section-table-cell"><%=gw.ipv6 and luci.i18n.translate('yes') or luci.i18n.translate('no')%></td>
<td class="cbi-section-table-cell"><%=gw.externalPrefix%></td>
</tr>
<div class="td cbi-section-table-cell"><%=gw.ipv4Status or gw.ipv6Status or '-' %></div>
<div class="td cbi-section-table-cell"><%=string.format("%.3f", gw.tcPathCost)%></div>
<div class="td cbi-section-table-cell"><%=gw.hopCount%></div>
<div class="td cbi-section-table-cell"><%=gw.uplinkSpeed%></div>
<div class="td cbi-section-table-cell"><%=gw.downlinkSpeed%></div>
<div class="td cbi-section-table-cell"><%=gw.ipv4 and luci.i18n.translate('yes') or luci.i18n.translate('no')%></div>
<div class="td cbi-section-table-cell"><%=gw.ipv6 and luci.i18n.translate('yes') or luci.i18n.translate('no')%></div>
<div class="td cbi-section-table-cell"><%=gw.externalPrefix%></div>
</div>
<% i = ((i % 2) + 1)
end %>
</tbody>
</table>
</div>
</div>
</fieldset>
<% else %>

View file

@ -17,14 +17,14 @@ local olsrtools = require "luci.tools.olsr"
<fieldset class="cbi-section">
<legend><%:Overview of currently known OLSR nodes%></legend>
<table class="cbi-section-table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:OLSR node%></th>
<th class="cbi-section-table-cell"><%:Last hop%></th>
<th class="cbi-section-table-cell"><%:LQ%></th>
<th class="cbi-section-table-cell"><%:NLQ%></th>
<th class="cbi-section-table-cell"><%:ETX%></th>
</tr>
<div class="table cbi-section-table">
<div class="tr cbi-section-table-titles">
<div class="th cbi-section-table-cell"><%:OLSR node%></div>
<div class="th cbi-section-table-cell"><%:Last hop%></div>
<div class="th cbi-section-table-cell"><%:LQ%></div>
<div class="th cbi-section-table-cell"><%:NLQ%></div>
<div class="th cbi-section-table-cell"><%:ETX%></div>
</div>
<% for k, route in ipairs(routes) do
local cost = string.format("%.3f", tonumber(route.tcEdgeCost/1024) or 0)
@ -33,28 +33,28 @@ local olsrtools = require "luci.tools.olsr"
local nlq = string.format("%.3f", tonumber(route.neighborLinkQuality) or 0)
%>
<tr class="cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=route.proto%>">
<div class="tr cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=route.proto%>">
<% if route.proto == "6" then %>
<td class="cbi-section-table-cell"><a href="http://[<%=route.destinationIP%>]/cgi-bin-status.html"><%=route.destinationIP%></a></td>
<td class="cbi-section-table-cell"><a href="http://[<%=route.lastHopIP%>]/cgi-bin-status.html"><%=route.lastHopIP%></a></td>
<div class="td cbi-section-table-cell"><a href="http://[<%=route.destinationIP%>]/cgi-bin-status.html"><%=route.destinationIP%></a></div>
<div class="td cbi-section-table-cell"><a href="http://[<%=route.lastHopIP%>]/cgi-bin-status.html"><%=route.lastHopIP%></a></div>
<% else %>
<td class="cbi-section-table-cell"><a href="http://<%=route.destinationIP%>/cgi-bin-status.html"><%=route.destinationIP%></a></td>
<td class="cbi-section-table-cell"><a href="http://<%=route.lastHopIP%>/cgi-bin-status.html"><%=route.lastHopIP%></a></td>
<div class="td cbi-section-table-cell"><a href="http://<%=route.destinationIP%>/cgi-bin-status.html"><%=route.destinationIP%></a></div>
<div class="td cbi-section-table-cell"><a href="http://<%=route.lastHopIP%>/cgi-bin-status.html"><%=route.lastHopIP%></a></div>
<%end%>
<td class="cbi-section-table-cell"><%=lq%></td>
<td class="cbi-section-table-cell"><%=nlq%></td>
<td class="cbi-section-table-cell" style="background-color:<%=color%>"><%=cost%></td>
</tr>
<div class="td cbi-section-table-cell"><%=lq%></div>
<div class="td cbi-section-table-cell"><%=nlq%></div>
<div class="td cbi-section-table-cell" style="background-color:<%=color%>"><%=cost%></div>
</div>
<% i = ((i % 2) + 1)
end %>
</table>
</div>
<%+status-olsr/legend%>
</fieldset>

View file

@ -56,7 +56,7 @@ function s.create(self, name)
luci.cbi.CREATE_PREFIX .. self.config .. "." ..
self.sectiontype .. ".text"
)
if string.len(name)>3 and not name:match("[^a-zA-Z0-9_]") then
if #name > 3 and not name:match("[^a-zA-Z0-9_]") then
uci:section(
"openvpn", "openvpn", name,
uci:get_all( "openvpn_recipes", recipe )
@ -67,9 +67,11 @@ function s.create(self, name)
uci:save("openvpn")
luci.http.redirect( self.extedit:format(name) )
else
elseif #name > 0 then
self.invalid_cts = true
end
return 0
end
@ -103,10 +105,7 @@ function updown.cfgvalue(self, section)
end
function updown.write(self, section, value)
if self.option == "stop" then
local pid = s.getPID(section)
if pid ~= nil then
sys.process.signal(pid,15)
end
luci.sys.call("/etc/init.d/openvpn stop %s" % section)
else
luci.sys.call("/etc/init.d/openvpn start %s" % section)
end
@ -126,5 +125,8 @@ function proto.cfgvalue(self, section)
return val or "udp"
end
function m.on_after_commit(self,map)
require("luci.sys").call('/etc/init.d/openvpn reload')
end
return m

View file

@ -2,12 +2,23 @@
<div class="errorbox"><%=pcdata(msg)%></div>
<%- end end -%>
<%-+cbi/apply_xhr-%>
<div class="cbi-map" id="cbi-<%=self.config%>">
<% if self.title and #self.title > 0 then %><h2 name="content"><%=self.title%></h2><% end %>
<% if self.description and #self.description > 0 then %><div class="cbi-map-descr"><%=self.description%></div><% end %>
<%- if firstmap and applymap then cbi_apply_xhr(self.config, parsechain, redirect) end -%>
<%- if firstmap and (applymap or confirmmap) then -%>
<%+cbi/apply_widget%>
<% cbi_apply_widget() %>
<div class="alert-message" id="cbi_apply_status" style="display:none"></div>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function() {
<% if confirmmap then -%>
uci_confirm(true, Date.now() + <%=confirmmap%> * 1000);
<%- else -%>
uci_apply(true);
<%- end %>
});
</script>
<%- end -%>
<% if self.tabbed then %>
<ul class="cbi-tabmenu map">

View file

@ -7,7 +7,7 @@
include $(TOPDIR)/rules.mk
LUCI_TITLE:=Roaring Penguing PPPoE Server
LUCI_TITLE:=Roaring Penguin PPPoE Server
LUCI_DEPENDS:=+rp-pppoe-server
include ../../luci.mk

View file

@ -1,24 +1,17 @@
<div class="cbi-section-create cbi-tblsection-create">
<br />
<table class="cbi-section-table">
<tr class="cbi-section-table-row">
<td class="cbi-section-table-cell" style="width:140px">
<select class="cbi-input-select" id="_newinst.type" name="_newinst.type">
<option value="_dummy">-- instance type --</option>
<option value="ss_local">ss-local</option>
<option value="ss_tunnel">ss-tunnel</option>
<option value="ss_redir">ss-redir</option>
<option value="ss_server">ss-server</option>
</select>
</td>
<td class="cbi-section-table-cell" style="width:110px">
<input type="text" class="cbi-input-text" id="_newinst.name" name="_newinst.name" placeholder="<%:Name%>"/>
</td>
<td class="cbi-section-table-cell left">
<input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>" value="<%:Add%>" />
</td>
</tr>
</table>
<div>
<select class="cbi-input-select" id="_newinst.type" name="_newinst.type">
<option value="_dummy">-- instance type --</option>
<option value="ss_local">ss-local</option>
<option value="ss_tunnel">ss-tunnel</option>
<option value="ss_redir">ss-redir</option>
<option value="ss_server">ss-server</option>
</select>
</div>
<div>
<input type="text" class="cbi-input-text" id="_newinst.name" name="_newinst.name" placeholder="<%:Name%>"/>
</div>
<input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>" value="<%:Add%>" />
</div>
<script type="text/javascript">//<![CDATA[
XHR.poll(5, '<%=url('admin/services/shadowsocks-libev/status')%>', null,

View file

@ -134,7 +134,6 @@ end
<%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript">//<![CDATA[
XHR.poll(10 , '<%=REQUEST_URI%>', { status: 1 },
@ -145,19 +144,19 @@ end
{
var s = '';
if (info.length == undefined) {
s += '<tr class="cbi-section-table-row"><td colspan="7" class="cbi-section-table-cell"><br /><em><%:No clients connected%></em><br /></td></tr>'
s += '<div class="tr cbi-section-table-row"><div colspan="7" class="td cbi-section-table-cell"><br /><em><%:No clients connected%></em><br /></div></div>'
};
for (var idx = 0; idx < info.length; idx++)
{
var splash = info[idx];
s += String.format(
'<tr class="cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+'">' +
'<td class="cbi-section-table-cell">%s</td>' +
'<td class="cbi-section-table-cell">%s</td>' +
'<td class="cbi-section-table-cell">%s</td>' +
'<td class="cbi-section-table-cell">%s</td>' +
'<td class="cbi-section-table-cell">%s/%s</td>' +
'<td class="cbi-section-table-cell">',
'<div class="tr cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+'">' +
'<div class="td cbi-section-table-cell">%s</div>' +
'<div class="td cbi-section-table-cell">%s</div>' +
'<div class="td cbi-section-table-cell">%s</div>' +
'<div class="td cbi-section-table-cell">%s</div>' +
'<div class="td cbi-section-table-cell">%s/%s</div>' +
'<div class="td cbi-section-table-cell">',
splash.hostname, splash.ip, splash.mac, splash.timeleft, splash.trafficin, splash.trafficout);
<% if is_admin then %>
@ -185,7 +184,7 @@ end
<% else %>
s += String.format('%s', splash.policy);
<% end %>
s += '</td></tr>'
s += '</div></div>'
}
tbody.innerHTML = s;
}
@ -200,18 +199,18 @@ end
<legend><%:Active Clients%></legend>
<div class="cbi-section-node">
<% if is_admin then %><form action="<%=REQUEST_URI%>" method="post"><input type="hidden" name="token" value="<%=token%>" /><% end %>
<table class="cbi-section-table">
<thead>
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Hostname%></th>
<th class="cbi-section-table-cell"><%:IP Address%></th>
<th class="cbi-section-table-cell"><%:MAC Address%></th>
<th class="cbi-section-table-cell"><%:Time remaining%></th>
<th class="cbi-section-table-cell"><%:Traffic in/out%></th>
<th class="cbi-section-table-cell"><%:Policy%></th>
</tr>
</thead>
<tbody id="splash_table">
<div class="table cbi-section-table">
<div class="thead">
<div class="tr cbi-section-table-titles">
<div class="th cbi-section-table-cell"><%:Hostname%></div>
<div class="th cbi-section-table-cell"><%:IP Address%></div>
<div class="th cbi-section-table-cell"><%:MAC Address%></div>
<div class="th cbi-section-table-cell"><%:Time remaining%></div>
<div class="th cbi-section-table-cell"><%:Traffic in/out%></div>
<div class="th cbi-section-table-cell"><%:Policy%></div>
</div>
</div>
<div class="tbody" id="splash_table">
<%-
local count = 0
@ -227,16 +226,16 @@ end
if c.ip then
count = count + 1
-%>
<tr class="cbi-section-table-row cbi-rowstyle-<%=2-(count%2)%>">
<td class="cbi-section-table-cell"><%=c.hostname or "<em>" .. translate("unknown") .. "</em>"%></td>
<td class="cbi-section-table-cell"><%=c.ip or "<em>" .. translate("unknown") .. "</em>"%></td>
<td class="cbi-section-table-cell"><%=showmac(c.mac)%></td>
<td class="cbi-section-table-cell"><%=
<div class="tr cbi-section-table-row cbi-rowstyle-<%=2-(count%2)%>">
<div class="td cbi-section-table-cell"><%=c.hostname or "<em>" .. translate("unknown") .. "</em>"%></div>
<div class="td cbi-section-table-cell"><%=c.ip or "<em>" .. translate("unknown") .. "</em>"%></div>
<div class="td cbi-section-table-cell"><%=showmac(c.mac)%></div>
<div class="td cbi-section-table-cell"><%=
(c.limit >= os.time()) and wat.date_format(c.limit-os.time()) or
(c.policy ~= "normal") and "-" or "<em>" .. translate("expired") .. "</em>"
%></td>
<td class="cbi-section-table-cell"><%=wat.byte_format(c.bytes_in)%> / <%=wat.byte_format(c.bytes_out)%></td>
<td class="cbi-section-table-cell">
%></div>
<div class="td cbi-section-table-cell"><%=wat.byte_format(c.bytes_in)%> / <%=wat.byte_format(c.bytes_out)%></div>
<div class="td cbi-section-table-cell">
<% if is_admin then %>
<select name="policy.<%=c.mac:lower()%>" style="width:200px">
<option value="whitelist"<%=c.policy=="whitelist" and ' selected="selected"'%>><%:whitelisted%></option>
@ -250,21 +249,21 @@ end
<% else %>
<%=c.policy%>
<% end %>
</td>
</tr>
</div>
</div>
<%-
end
end
if count == 0 then
-%>
<tr class="cbi-section-table-row">
<td colspan="7" class="cbi-section-table-cell">
<div class="tr cbi-section-table-row">
<div colspan="7" class="td cbi-section-table-cell">
<br /><em><%:No clients connected%></em><br />
</td>
</tr>
</div>
</div>
<%- end -%>
</tbody>
</table>
</div>
</div>
<% if is_admin then %></form><% end %>
</div>
</fieldset>

Some files were not shown because too many files have changed in this diff Show more