summaryrefslogtreecommitdiffhomepage
path: root/modules/luci-base/luasrc
diff options
context:
space:
mode:
Diffstat (limited to 'modules/luci-base/luasrc')
-rw-r--r--modules/luci-base/luasrc/cbi/datatypes.lua78
-rw-r--r--modules/luci-base/luasrc/dispatcher.lua174
-rw-r--r--modules/luci-base/luasrc/http.lua10
-rw-r--r--modules/luci-base/luasrc/http/protocol.lua4
-rw-r--r--modules/luci-base/luasrc/model/cbi/admin_network/proto_static.lua9
-rw-r--r--modules/luci-base/luasrc/model/firewall.lua6
-rw-r--r--modules/luci-base/luasrc/model/network.lua9
-rw-r--r--modules/luci-base/luasrc/sys.lua208
-rw-r--r--modules/luci-base/luasrc/sys/zoneinfo/tzdata.lua263
-rw-r--r--modules/luci-base/luasrc/sys/zoneinfo/tzoffset.lua93
-rw-r--r--modules/luci-base/luasrc/tools/status.lua10
-rw-r--r--modules/luci-base/luasrc/view/cbi/firewall_zoneforwards.htm5
12 files changed, 365 insertions, 504 deletions
diff --git a/modules/luci-base/luasrc/cbi/datatypes.lua b/modules/luci-base/luasrc/cbi/datatypes.lua
index 98f6a44d77..df23aaf135 100644
--- a/modules/luci-base/luasrc/cbi/datatypes.lua
+++ b/modules/luci-base/luasrc/cbi/datatypes.lua
@@ -1,4 +1,5 @@
-- Copyright 2010 Jo-Philipp Wich <jow@openwrt.org>
+-- Copyright 2017 Dan Luedtke <mail@danrl.com>
-- Licensed to the public under the Apache License 2.0.
local fs = require "nixio.fs"
@@ -131,38 +132,48 @@ function ip6prefix(val)
return ( val and val >= 0 and val <= 128 )
end
-function ipmask(val)
- return ipmask4(val) or ipmask6(val)
+function cidr4(val)
+ local ip, mask = val:match("^([^/]+)/([^/]+)$")
+
+ return ip4addr(ip) and ip4prefix(mask)
end
-function ipmask4(val)
+function cidr6(val)
local ip, mask = val:match("^([^/]+)/([^/]+)$")
- local bits = tonumber(mask)
- if bits and (bits < 0 or bits > 32) then
- return false
- end
+ return ip6addr(ip) and ip6prefix(mask)
+end
- if not bits and not ip4addr(mask) then
- return false
- end
+function ipnet4(val)
+ local ip, mask = val:match("^([^/]+)/([^/]+)$")
- return ip4addr(ip or val)
+ return ip4addr(ip) and ip4addr(mask)
end
-function ipmask6(val)
+function ipnet6(val)
local ip, mask = val:match("^([^/]+)/([^/]+)$")
- local bits = tonumber(mask)
- if bits and (bits < 0 or bits > 128) then
- return false
- end
+ return ip6addr(ip) and ip6addr(mask)
+end
- if not bits and not ip6addr(mask) then
- return false
+function ipmask(val)
+ return ipmask4(val) or ipmask6(val)
+end
+
+function ipmask4(val)
+ return cidr4(val) or ipnet4(val) or ip4addr(val)
+end
+
+function ipmask6(val)
+ return cidr6(val) or ipnet6(val) or ip6addr(val)
+end
+
+function ip6hostid(val)
+ if val and val:match("^[a-fA-F0-9:]+$") and (#val > 2) then
+ return (ip6addr("2001:db8:0:0" .. val) or ip6addr("2001:db8:0:0:" .. val))
end
- return ip6addr(ip or val)
+ return false
end
function port(val)
@@ -267,11 +278,33 @@ function wepkey(val)
end
end
+function hexstring(val)
+ if val then
+ return (val:match("^[a-fA-F0-9]+$") ~= nil)
+ end
+ return false
+end
+
+function hex(val, maxbytes)
+ maxbytes = tonumber(maxbytes)
+ if val and maxbytes ~= nil then
+ return ((val:match("^0x[a-fA-F0-9]+$") ~= nil) and (#val <= 2 + maxbytes * 2))
+ end
+ return false
+end
+
+function base64(val)
+ if val then
+ return (val:match("^[a-zA-Z0-9/+]+=?=?$") ~= nil) and (math.fmod(#val, 4) == 0)
+ end
+ return false
+end
+
function string(val)
return true -- Everything qualifies as valid string
end
-function directory( val, seen )
+function directory(val, seen)
local s = fs.stat(val)
seen = seen or { }
@@ -287,7 +320,7 @@ function directory( val, seen )
return false
end
-function file( val, seen )
+function file(val, seen)
local s = fs.stat(val)
seen = seen or { }
@@ -303,7 +336,7 @@ function file( val, seen )
return false
end
-function device( val, seen )
+function device(val, seen)
local s = fs.stat(val)
seen = seen or { }
@@ -438,4 +471,3 @@ function dateyyyymmdd(val)
end
return false
end
-
diff --git a/modules/luci-base/luasrc/dispatcher.lua b/modules/luci-base/luasrc/dispatcher.lua
index 0876ce6585..e4f77f18d8 100644
--- a/modules/luci-base/luasrc/dispatcher.lua
+++ b/modules/luci-base/luasrc/dispatcher.lua
@@ -14,8 +14,6 @@ uci = require "luci.model.uci"
i18n = require "luci.i18n"
_M.fs = fs
-authenticator = {}
-
-- Index table
local index = nil
@@ -101,24 +99,6 @@ function error500(message)
return false
end
-function authenticator.htmlauth(validator, accs, default)
- local user = http.formvalue("luci_username")
- local pass = http.formvalue("luci_password")
-
- if user and validator(user, pass) then
- return user
- end
-
- require("luci.i18n")
- require("luci.template")
- context.path = {}
- http.status(403, "Forbidden")
- luci.template.render("sysauth", {duser=default, fuser=user})
-
- return false
-
-end
-
function httpdispatch(request, prefix)
http.context.request = request
@@ -188,6 +168,44 @@ function test_post_security()
return true
end
+local function session_retrieve(sid, allowed_users)
+ local sdat = util.ubus("session", "get", { ubus_rpc_session = sid })
+
+ if type(sdat) == "table" and
+ type(sdat.values) == "table" and
+ type(sdat.values.token) == "string" and
+ (not allowed_users or
+ util.contains(allowed_users, sdat.values.username))
+ then
+ return sid, sdat.values
+ end
+
+ return nil, nil
+end
+
+local function session_setup(user, pass, allowed_users)
+ if util.contains(allowed_users, user) then
+ local login = util.ubus("session", "login", {
+ username = user,
+ password = pass,
+ timeout = tonumber(luci.config.sauth.sessiontime)
+ })
+
+ if type(login) == "table" and
+ type(login.ubus_rpc_session) == "string"
+ then
+ util.ubus("session", "set", {
+ ubus_rpc_session = login.ubus_rpc_session,
+ values = { token = sys.uniqueid(16) }
+ })
+
+ return session_retrieve(login.ubus_rpc_session)
+ end
+ end
+
+ return nil, nil
+end
+
function dispatch(request)
--context._disable_memtrace = require "luci.debug".trap_memtrace("l")
local ctx = context
@@ -201,10 +219,19 @@ function dispatch(request)
local lang = conf.main.lang or "auto"
if lang == "auto" then
local aclang = http.getenv("HTTP_ACCEPT_LANGUAGE") or ""
- for lpat in aclang:gmatch("[%w-]+") do
- lpat = lpat and lpat:gsub("-", "_")
- if conf.languages[lpat] then
- lang = lpat
+ for aclang in aclang:gmatch("[%w_-]+") do
+ local country, culture = aclang:match("^([a-z][a-z])[_-]([a-zA-Z][a-zA-Z])$")
+ if country and culture then
+ local cc = "%s_%s" %{ country, culture:lower() }
+ if conf.languages[cc] then
+ lang = cc
+ break
+ elseif conf.languages[country] then
+ lang = country
+ break
+ end
+ elseif conf.languages[aclang] then
+ lang = aclang
break
end
end
@@ -332,74 +359,65 @@ function dispatch(request)
)
if track.sysauth then
- local authen = type(track.sysauth_authenticator) == "function"
- and track.sysauth_authenticator
- or authenticator[track.sysauth_authenticator]
+ local authen = track.sysauth_authenticator
+ local _, sid, sdat, default_user, allowed_users
- local def = (type(track.sysauth) == "string") and track.sysauth
- local accs = def and {track.sysauth} or track.sysauth
- local sess = ctx.authsession
- if not sess then
- sess = http.getcookie("sysauth")
- sess = sess and sess:match("^[a-f0-9]*$")
+ if type(authen) == "string" and authen ~= "htmlauth" then
+ error500("Unsupported authenticator %q configured" % authen)
+ return
end
- local sdat = (util.ubus("session", "get", { ubus_rpc_session = sess }) or { }).values
- local user, token
+ if type(track.sysauth) == "table" then
+ default_user, allowed_users = nil, track.sysauth
+ else
+ default_user, allowed_users = track.sysauth, { track.sysauth }
+ end
- if sdat then
- user = sdat.user
- token = sdat.token
+ if type(authen) == "function" then
+ _, sid = authen(sys.user.checkpasswd, allowed_users)
else
- local eu = http.getenv("HTTP_AUTH_USER")
- local ep = http.getenv("HTTP_AUTH_PASS")
- if eu and ep and sys.user.checkpasswd(eu, ep) then
- authen = function() return eu end
- end
+ sid = http.getcookie("sysauth")
end
- if not util.contains(accs, user) then
- if authen then
- local user, sess = authen(sys.user.checkpasswd, accs, def)
- local token
- if not user or not util.contains(accs, user) then
- return
- else
- if not sess then
- local sdat = util.ubus("session", "create", { timeout = tonumber(luci.config.sauth.sessiontime) })
- if sdat then
- token = sys.uniqueid(16)
- util.ubus("session", "set", {
- ubus_rpc_session = sdat.ubus_rpc_session,
- values = {
- user = user,
- token = token,
- section = sys.uniqueid(16)
- }
- })
- sess = sdat.ubus_rpc_session
- end
- end
+ sid, sdat = session_retrieve(sid, allowed_users)
- if sess and token then
- http.header("Set-Cookie", 'sysauth=%s; path=%s' %{ sess, build_url() })
+ if not (sid and sdat) and authen == "htmlauth" then
+ local user = http.getenv("HTTP_AUTH_USER")
+ local pass = http.getenv("HTTP_AUTH_PASS")
- ctx.authsession = sess
- ctx.authtoken = token
- ctx.authuser = user
+ if user == nil and pass == nil then
+ user = http.formvalue("luci_username")
+ pass = http.formvalue("luci_password")
+ end
+
+ sid, sdat = session_setup(user, pass, allowed_users)
+
+ if not sid then
+ local tmpl = require "luci.template"
+
+ context.path = {}
- http.redirect(build_url(unpack(ctx.requestpath)))
- end
- end
- else
http.status(403, "Forbidden")
+ tmpl.render(track.sysauth_template or "sysauth", {
+ duser = default_user,
+ fuser = user
+ })
+
return
end
- else
- ctx.authsession = sess
- ctx.authtoken = token
- ctx.authuser = user
+
+ http.header("Set-Cookie", 'sysauth=%s; path=%s' %{ sid, build_url() })
+ http.redirect(build_url(unpack(ctx.requestpath)))
end
+
+ if not sid or not sdat then
+ http.status(403, "Forbidden")
+ return
+ end
+
+ ctx.authsession = sid
+ ctx.authtoken = sdat.token
+ ctx.authuser = sdat.username
end
if c and require_post_security(c.target) then
diff --git a/modules/luci-base/luasrc/http.lua b/modules/luci-base/luasrc/http.lua
index 8795dfc4b2..9cc9857867 100644
--- a/modules/luci-base/luasrc/http.lua
+++ b/modules/luci-base/luasrc/http.lua
@@ -224,7 +224,15 @@ function write(content, src_err)
header("Cache-Control", "no-cache")
header("Expires", "0")
end
-
+ if not context.headers["x-frame-options"] then
+ header("X-Frame-Options", "SAMEORIGIN")
+ end
+ if not context.headers["x-xss-protection"] then
+ header("X-XSS-Protection", "1; mode=block")
+ end
+ if not context.headers["x-content-type-options"] then
+ header("X-Content-Type-Options", "nosniff")
+ end
context.eoh = true
coroutine.yield(3)
diff --git a/modules/luci-base/luasrc/http/protocol.lua b/modules/luci-base/luasrc/http/protocol.lua
index 061c6ad544..0a8b2fbab9 100644
--- a/modules/luci-base/luasrc/http/protocol.lua
+++ b/modules/luci-base/luasrc/http/protocol.lua
@@ -264,7 +264,7 @@ function header_source( sock )
end
-- Content-Type. Stores all extracted data associated with its parameter name
--- in the params table withing the given message object. Multiple parameter
+-- in the params table within the given message object. Multiple parameter
-- values are stored as tables, ordinary ones as strings.
-- If an optional file callback function is given then it is feeded with the
-- file contents chunk by chunk and only the extracted file name is stored
@@ -433,7 +433,7 @@ function mimedecode_message_body( src, msg, filecb )
end
-- Content-Type. Stores all extracted data associated with its parameter name
--- in the params table withing the given message object. Multiple parameter
+-- in the params table within the given message object. Multiple parameter
-- values are stored as tables, ordinary ones as strings.
function urldecode_message_body( src, msg )
diff --git a/modules/luci-base/luasrc/model/cbi/admin_network/proto_static.lua b/modules/luci-base/luasrc/model/cbi/admin_network/proto_static.lua
index f49fed4a56..3f8b091cf3 100644
--- a/modules/luci-base/luasrc/model/cbi/admin_network/proto_static.lua
+++ b/modules/luci-base/luasrc/model/cbi/admin_network/proto_static.lua
@@ -63,6 +63,15 @@ if luci.model.network:has_ipv6() then
ip6prefix.datatype = "ip6addr"
ip6prefix:depends("ip6assign", "")
+ local ip6ifaceid = s:taboption("general", Value, "ip6ifaceid", translate("IPv6 suffix"),
+ translate("Optional. Allowed values: 'eui64', 'random', fixed value like '::1' " ..
+ "or '::1:2'. When IPv6 prefix (like 'a:b:c:d::') is received from a " ..
+ "delegating server, use the suffix (like '::1') to form the IPv6 address " ..
+ "('a:b:c:d::1') for the interface."))
+ ip6ifaceid.datatype = "ip6hostid"
+ ip6ifaceid.placeholder = "::1"
+ ip6ifaceid.rmempty = true
+
end
diff --git a/modules/luci-base/luasrc/model/firewall.lua b/modules/luci-base/luasrc/model/firewall.lua
index 5573a9b86c..feff0855c4 100644
--- a/modules/luci-base/luasrc/model/firewall.lua
+++ b/modules/luci-base/luasrc/model/firewall.lua
@@ -498,11 +498,13 @@ function forwarding.dest(self)
end
function forwarding.src_zone(self)
- return zone(self:src())
+ local z = zone(self:src())
+ return z.sid and z
end
function forwarding.dest_zone(self)
- return zone(self:dest())
+ local z = zone(self:dest())
+ return z.sid and z
end
diff --git a/modules/luci-base/luasrc/model/network.lua b/modules/luci-base/luasrc/model/network.lua
index 2d8336bf33..d9ef4089c8 100644
--- a/modules/luci-base/luasrc/model/network.lua
+++ b/modules/luci-base/luasrc/model/network.lua
@@ -950,6 +950,13 @@ function protocol.dns6addrs(self)
return dns
end
+function protocol.ip6prefix(self)
+ local prefix = self:_ubus("ipv6-prefix")
+ if prefix and #prefix > 0 then
+ return "%s/%d" %{ prefix[1].address, prefix[1].mask }
+ end
+end
+
function protocol.is_bridge(self)
return (not self:is_virtual() and self:type() == "bridge")
end
@@ -1355,8 +1362,6 @@ function wifidev.get_i18n(self)
local t = "Generic"
if self.iwinfo.type == "wl" then
t = "Broadcom"
- elseif self.iwinfo.type == "madwifi" then
- t = "Atheros"
end
local m = ""
diff --git a/modules/luci-base/luasrc/sys.lua b/modules/luci-base/luasrc/sys.lua
index a97271732a..115c54d54a 100644
--- a/modules/luci-base/luasrc/sys.lua
+++ b/modules/luci-base/luasrc/sys.lua
@@ -117,45 +117,12 @@ end
net = {}
--- The following fields are defined for arp entry objects:
--- { "IP address", "HW address", "HW type", "Flags", "Mask", "Device" }
-function net.arptable(callback)
- local arp = (not callback) and {} or nil
- local e, r, v
- if fs.access("/proc/net/arp") then
- for e in io.lines("/proc/net/arp") do
- local r = { }, v
- for v in e:gmatch("%S+") do
- r[#r+1] = v
- end
-
- if r[1] ~= "IP" then
- local x = {
- ["IP address"] = r[1],
- ["HW type"] = r[2],
- ["Flags"] = r[3],
- ["HW address"] = r[4],
- ["Mask"] = r[5],
- ["Device"] = r[6]
- }
-
- if callback then
- callback(x)
- else
- arp = arp or { }
- arp[#arp+1] = x
- end
- end
- end
- end
- return arp
-end
-
local function _nethints(what, callback)
local _, k, e, mac, ip, name
local cur = uci.cursor()
local ifn = { }
local hosts = { }
+ local lookup = { }
local function _add(i, ...)
local k = select(i, ...)
@@ -224,8 +191,20 @@ local function _nethints(what, callback)
end
end
+ for _, e in pairs(hosts) do
+ lookup[#lookup+1] = (what > 1) and e[what] or (e[2] or e[3])
+ end
+
+ if #lookup > 0 then
+ lookup = luci.util.ubus("network.rrdns", "lookup", {
+ addrs = lookup,
+ timeout = 250,
+ limit = 1000
+ }) or { }
+ end
+
for _, e in luci.util.kspairs(hosts) do
- callback(e[1], e[2], e[3], e[4])
+ callback(e[1], e[2], e[3], lookup[e[2]] or lookup[e[3]] or e[4])
end
end
@@ -234,17 +213,17 @@ end
function net.mac_hints(callback)
if callback then
_nethints(1, function(mac, v4, v6, name)
- name = name or nixio.getnameinfo(v4 or v6, nil, 100) or v4
+ name = name or v4
if name and name ~= mac then
- callback(mac, name or nixio.getnameinfo(v4 or v6, nil, 100) or v4)
+ callback(mac, name or v4)
end
end)
else
local rv = { }
_nethints(1, function(mac, v4, v6, name)
- name = name or nixio.getnameinfo(v4 or v6, nil, 100) or v4
+ name = name or v4
if name and name ~= mac then
- rv[#rv+1] = { mac, name or nixio.getnameinfo(v4 or v6, nil, 100) or v4 }
+ rv[#rv+1] = { mac, name or v4 }
end
end)
return rv
@@ -256,7 +235,7 @@ end
function net.ipv4_hints(callback)
if callback then
_nethints(2, function(mac, v4, v6, name)
- name = name or nixio.getnameinfo(v4, nil, 100) or mac
+ name = name or mac
if name and name ~= v4 then
callback(v4, name)
end
@@ -264,7 +243,7 @@ function net.ipv4_hints(callback)
else
local rv = { }
_nethints(2, function(mac, v4, v6, name)
- name = name or nixio.getnameinfo(v4, nil, 100) or mac
+ name = name or mac
if name and name ~= v4 then
rv[#rv+1] = { v4, name }
end
@@ -278,7 +257,7 @@ end
function net.ipv6_hints(callback)
if callback then
_nethints(3, function(mac, v4, v6, name)
- name = name or nixio.getnameinfo(v6, nil, 100) or mac
+ name = name or mac
if name and name ~= v6 then
callback(v6, name)
end
@@ -286,7 +265,7 @@ function net.ipv6_hints(callback)
else
local rv = { }
_nethints(3, function(mac, v4, v6, name)
- name = name or nixio.getnameinfo(v6, nil, 100) or mac
+ name = name or mac
if name and name ~= v6 then
rv[#rv+1] = { v6, name }
end
@@ -369,8 +348,10 @@ end
function net.devices()
local devs = {}
+ local seen = {}
for k, v in ipairs(nixio.getifaddrs()) do
- if v.family == "packet" then
+ if v.name and not seen[v.name] then
+ seen[v.name] = true
devs[#devs+1] = v.name
end
end
@@ -378,145 +359,6 @@ function net.devices()
end
-function net.deviceinfo()
- local devs = {}
- for k, v in ipairs(nixio.getifaddrs()) do
- if v.family == "packet" then
- local d = v.data
- d[1] = d.rx_bytes
- d[2] = d.rx_packets
- d[3] = d.rx_errors
- d[4] = d.rx_dropped
- d[5] = 0
- d[6] = 0
- d[7] = 0
- d[8] = d.multicast
- d[9] = d.tx_bytes
- d[10] = d.tx_packets
- d[11] = d.tx_errors
- d[12] = d.tx_dropped
- d[13] = 0
- d[14] = d.collisions
- d[15] = 0
- d[16] = 0
- devs[v.name] = d
- end
- end
- return devs
-end
-
-
--- The following fields are defined for route entry tables:
--- { "dest", "gateway", "metric", "refcount", "usecount", "irtt",
--- "flags", "device" }
-function net.routes(callback)
- local routes = { }
-
- for line in io.lines("/proc/net/route") do
-
- local dev, dst_ip, gateway, flags, refcnt, usecnt, metric,
- dst_mask, mtu, win, irtt = line:match(
- "([^%s]+)\t([A-F0-9]+)\t([A-F0-9]+)\t([A-F0-9]+)\t" ..
- "(%d+)\t(%d+)\t(%d+)\t([A-F0-9]+)\t(%d+)\t(%d+)\t(%d+)"
- )
-
- if dev then
- gateway = luci.ip.Hex( gateway, 32, luci.ip.FAMILY_INET4 )
- dst_mask = luci.ip.Hex( dst_mask, 32, luci.ip.FAMILY_INET4 )
- dst_ip = luci.ip.Hex(
- dst_ip, dst_mask:prefix(dst_mask), luci.ip.FAMILY_INET4
- )
-
- local rt = {
- dest = dst_ip,
- gateway = gateway,
- metric = tonumber(metric),
- refcount = tonumber(refcnt),
- usecount = tonumber(usecnt),
- mtu = tonumber(mtu),
- window = tonumber(window),
- irtt = tonumber(irtt),
- flags = tonumber(flags, 16),
- device = dev
- }
-
- if callback then
- callback(rt)
- else
- routes[#routes+1] = rt
- end
- end
- end
-
- return routes
-end
-
--- The following fields are defined for route entry tables:
--- { "source", "dest", "nexthop", "metric", "refcount", "usecount",
--- "flags", "device" }
-function net.routes6(callback)
- if fs.access("/proc/net/ipv6_route", "r") then
- local routes = { }
-
- for line in io.lines("/proc/net/ipv6_route") do
-
- local dst_ip, dst_prefix, src_ip, src_prefix, nexthop,
- metric, refcnt, usecnt, flags, dev = line:match(
- "([a-f0-9]+) ([a-f0-9]+) " ..
- "([a-f0-9]+) ([a-f0-9]+) " ..
- "([a-f0-9]+) ([a-f0-9]+) " ..
- "([a-f0-9]+) ([a-f0-9]+) " ..
- "([a-f0-9]+) +([^%s]+)"
- )
-
- if dst_ip and dst_prefix and
- src_ip and src_prefix and
- nexthop and metric and
- refcnt and usecnt and
- flags and dev
- then
- src_ip = luci.ip.Hex(
- src_ip, tonumber(src_prefix, 16), luci.ip.FAMILY_INET6, false
- )
-
- dst_ip = luci.ip.Hex(
- dst_ip, tonumber(dst_prefix, 16), luci.ip.FAMILY_INET6, false
- )
-
- nexthop = luci.ip.Hex( nexthop, 128, luci.ip.FAMILY_INET6, false )
-
- local rt = {
- source = src_ip,
- dest = dst_ip,
- nexthop = nexthop,
- metric = tonumber(metric, 16),
- refcount = tonumber(refcnt, 16),
- usecount = tonumber(usecnt, 16),
- flags = tonumber(flags, 16),
- device = dev,
-
- -- lua number is too small for storing the metric
- -- add a metric_raw field with the original content
- metric_raw = metric
- }
-
- if callback then
- callback(rt)
- else
- routes[#routes+1] = rt
- end
- end
- end
-
- return routes
- end
-end
-
-function net.pingtest(host)
- return os.execute("ping -c1 '"..host:gsub("'", '').."' >/dev/null 2>&1")
-end
-
-
process = {}
function process.info(key)
diff --git a/modules/luci-base/luasrc/sys/zoneinfo/tzdata.lua b/modules/luci-base/luasrc/sys/zoneinfo/tzdata.lua
index 465d7df3d3..419c191f2b 100644
--- a/modules/luci-base/luasrc/sys/zoneinfo/tzdata.lua
+++ b/modules/luci-base/luasrc/sys/zoneinfo/tzdata.lua
@@ -59,42 +59,42 @@ TZ = {
{ 'America/Anchorage', 'AKST9AKDT,M3.2.0,M11.1.0' },
{ 'America/Anguilla', 'AST4' },
{ 'America/Antigua', 'AST4' },
- { 'America/Araguaina', 'BRT3' },
- { 'America/Argentina/Buenos Aires', 'ART3' },
- { 'America/Argentina/Catamarca', 'ART3' },
- { 'America/Argentina/Cordoba', 'ART3' },
- { 'America/Argentina/Jujuy', 'ART3' },
- { 'America/Argentina/La Rioja', 'ART3' },
- { 'America/Argentina/Mendoza', 'ART3' },
- { 'America/Argentina/Rio Gallegos', 'ART3' },
- { 'America/Argentina/Salta', 'ART3' },
- { 'America/Argentina/San Juan', 'ART3' },
- { 'America/Argentina/San Luis', 'ART3' },
- { 'America/Argentina/Tucuman', 'ART3' },
- { 'America/Argentina/Ushuaia', 'ART3' },
+ { 'America/Araguaina', '<-03>3' },
+ { 'America/Argentina/Buenos Aires', '<-03>3' },
+ { 'America/Argentina/Catamarca', '<-03>3' },
+ { 'America/Argentina/Cordoba', '<-03>3' },
+ { 'America/Argentina/Jujuy', '<-03>3' },
+ { 'America/Argentina/La Rioja', '<-03>3' },
+ { 'America/Argentina/Mendoza', '<-03>3' },
+ { 'America/Argentina/Rio Gallegos', '<-03>3' },
+ { 'America/Argentina/Salta', '<-03>3' },
+ { 'America/Argentina/San Juan', '<-03>3' },
+ { 'America/Argentina/San Luis', '<-03>3' },
+ { 'America/Argentina/Tucuman', '<-03>3' },
+ { 'America/Argentina/Ushuaia', '<-03>3' },
{ 'America/Aruba', 'AST4' },
- { 'America/Asuncion', 'PYT4PYST,M10.1.0/0,M3.4.0/0' },
+ { 'America/Asuncion', '<-04>4<-03>,M10.1.0/0,M3.4.0/0' },
{ 'America/Atikokan', 'EST5' },
- { 'America/Bahia', 'BRT3' },
+ { 'America/Bahia', '<-03>3' },
{ 'America/Bahia Banderas', 'CST6CDT,M4.1.0,M10.5.0' },
{ 'America/Barbados', 'AST4' },
- { 'America/Belem', 'BRT3' },
+ { 'America/Belem', '<-03>3' },
{ 'America/Belize', 'CST6' },
{ 'America/Blanc-Sablon', 'AST4' },
- { 'America/Boa Vista', 'AMT4' },
- { 'America/Bogota', 'COT5' },
+ { 'America/Boa Vista', '<-04>4' },
+ { 'America/Bogota', '<-05>5' },
{ 'America/Boise', 'MST7MDT,M3.2.0,M11.1.0' },
{ 'America/Cambridge Bay', 'MST7MDT,M3.2.0,M11.1.0' },
- { 'America/Campo Grande', 'AMT4AMST,M10.3.0/0,M2.3.0/0' },
+ { 'America/Campo Grande', '<-04>4<-03>,M10.3.0/0,M2.3.0/0' },
{ 'America/Cancun', 'EST5' },
- { 'America/Caracas', 'VET4' },
- { 'America/Cayenne', 'GFT3' },
+ { 'America/Caracas', '<-04>4' },
+ { 'America/Cayenne', '<-03>3' },
{ 'America/Cayman', 'EST5' },
{ 'America/Chicago', 'CST6CDT,M3.2.0,M11.1.0' },
{ 'America/Chihuahua', 'MST7MDT,M4.1.0,M10.5.0' },
{ 'America/Costa Rica', 'CST6' },
{ 'America/Creston', 'MST7' },
- { 'America/Cuiaba', 'AMT4AMST,M10.3.0/0,M2.3.0/0' },
+ { 'America/Cuiaba', '<-04>4<-03>,M10.3.0/0,M2.3.0/0' },
{ 'America/Curacao', 'AST4' },
{ 'America/Danmarkshavn', 'GMT0' },
{ 'America/Dawson', 'PST8PDT,M3.2.0,M11.1.0' },
@@ -103,19 +103,19 @@ TZ = {
{ 'America/Detroit', 'EST5EDT,M3.2.0,M11.1.0' },
{ 'America/Dominica', 'AST4' },
{ 'America/Edmonton', 'MST7MDT,M3.2.0,M11.1.0' },
- { 'America/Eirunepe', 'ACT5' },
+ { 'America/Eirunepe', '<-05>5' },
{ 'America/El Salvador', 'CST6' },
{ 'America/Fort Nelson', 'MST7' },
- { 'America/Fortaleza', 'BRT3' },
+ { 'America/Fortaleza', '<-03>3' },
{ 'America/Glace Bay', 'AST4ADT,M3.2.0,M11.1.0' },
- { 'America/Godthab', 'WGT3WGST,M3.5.0/-2,M10.5.0/-1' },
+ { 'America/Godthab', '<-03>3<-02>,M3.5.0/-2,M10.5.0/-1' },
{ 'America/Goose Bay', 'AST4ADT,M3.2.0,M11.1.0' },
{ 'America/Grand Turk', 'AST4' },
{ 'America/Grenada', 'AST4' },
{ 'America/Guadeloupe', 'AST4' },
{ 'America/Guatemala', 'CST6' },
- { 'America/Guayaquil', 'ECT5' },
- { 'America/Guyana', 'GYT4' },
+ { 'America/Guayaquil', '<-05>5' },
+ { 'America/Guyana', '<-04>4' },
{ 'America/Halifax', 'AST4ADT,M3.2.0,M11.1.0' },
{ 'America/Havana', 'CST5CDT,M3.2.0/0,M11.1.0/1' },
{ 'America/Hermosillo', 'MST7' },
@@ -134,13 +134,13 @@ TZ = {
{ 'America/Kentucky/Louisville', 'EST5EDT,M3.2.0,M11.1.0' },
{ 'America/Kentucky/Monticello', 'EST5EDT,M3.2.0,M11.1.0' },
{ 'America/Kralendijk', 'AST4' },
- { 'America/La Paz', 'BOT4' },
- { 'America/Lima', 'PET5' },
+ { 'America/La Paz', '<-04>4' },
+ { 'America/Lima', '<-05>5' },
{ 'America/Los Angeles', 'PST8PDT,M3.2.0,M11.1.0' },
{ 'America/Lower Princes', 'AST4' },
- { 'America/Maceio', 'BRT3' },
+ { 'America/Maceio', '<-03>3' },
{ 'America/Managua', 'CST6' },
- { 'America/Manaus', 'AMT4' },
+ { 'America/Manaus', '<-04>4' },
{ 'America/Marigot', 'AST4' },
{ 'America/Martinique', 'AST4' },
{ 'America/Matamoros', 'CST6CDT,M3.2.0,M11.1.0' },
@@ -149,39 +149,40 @@ TZ = {
{ 'America/Merida', 'CST6CDT,M4.1.0,M10.5.0' },
{ 'America/Metlakatla', 'AKST9AKDT,M3.2.0,M11.1.0' },
{ 'America/Mexico City', 'CST6CDT,M4.1.0,M10.5.0' },
- { 'America/Miquelon', 'PMST3PMDT,M3.2.0,M11.1.0' },
+ { 'America/Miquelon', '<-03>3<-02>,M3.2.0,M11.1.0' },
{ 'America/Moncton', 'AST4ADT,M3.2.0,M11.1.0' },
{ 'America/Monterrey', 'CST6CDT,M4.1.0,M10.5.0' },
- { 'America/Montevideo', 'UYT3' },
+ { 'America/Montevideo', '<-03>3' },
{ 'America/Montserrat', 'AST4' },
{ 'America/Nassau', 'EST5EDT,M3.2.0,M11.1.0' },
{ 'America/New York', 'EST5EDT,M3.2.0,M11.1.0' },
{ 'America/Nipigon', 'EST5EDT,M3.2.0,M11.1.0' },
{ 'America/Nome', 'AKST9AKDT,M3.2.0,M11.1.0' },
- { 'America/Noronha', 'FNT2' },
+ { 'America/Noronha', '<-02>2' },
{ 'America/North Dakota/Beulah', 'CST6CDT,M3.2.0,M11.1.0' },
{ 'America/North Dakota/Center', 'CST6CDT,M3.2.0,M11.1.0' },
{ 'America/North Dakota/New Salem', 'CST6CDT,M3.2.0,M11.1.0' },
{ 'America/Ojinaga', 'MST7MDT,M3.2.0,M11.1.0' },
{ 'America/Panama', 'EST5' },
{ 'America/Pangnirtung', 'EST5EDT,M3.2.0,M11.1.0' },
- { 'America/Paramaribo', 'SRT3' },
+ { 'America/Paramaribo', '<-03>3' },
{ 'America/Phoenix', 'MST7' },
{ 'America/Port of Spain', 'AST4' },
- { 'America/Port-au-Prince', 'EST5' },
- { 'America/Porto Velho', 'AMT4' },
+ { 'America/Port-au-Prince', 'EST5EDT,M3.2.0,M11.1.0' },
+ { 'America/Porto Velho', '<-04>4' },
{ 'America/Puerto Rico', 'AST4' },
+ { 'America/Punta Arenas', '<-03>3' },
{ 'America/Rainy River', 'CST6CDT,M3.2.0,M11.1.0' },
{ 'America/Rankin Inlet', 'CST6CDT,M3.2.0,M11.1.0' },
- { 'America/Recife', 'BRT3' },
+ { 'America/Recife', '<-03>3' },
{ 'America/Regina', 'CST6' },
{ 'America/Resolute', 'CST6CDT,M3.2.0,M11.1.0' },
- { 'America/Rio Branco', 'ACT5' },
- { 'America/Santarem', 'BRT3' },
- { 'America/Santiago', 'CLT4CLST,M8.2.6/24,M5.2.6/24' },
+ { 'America/Rio Branco', '<-05>5' },
+ { 'America/Santarem', '<-03>3' },
+ { 'America/Santiago', '<-04>4<-03>,M8.2.6/24,M5.2.6/24' },
{ 'America/Santo Domingo', 'AST4' },
- { 'America/Sao Paulo', 'BRT3BRST,M10.3.0/0,M2.3.0/0' },
- { 'America/Scoresbysund', 'EGT1EGST,M3.5.0/0,M10.5.0/1' },
+ { 'America/Sao Paulo', '<-03>3<-02>,M10.3.0/0,M2.3.0/0' },
+ { 'America/Scoresbysund', '<-01>1<+00>,M3.5.0/0,M10.5.0/1' },
{ 'America/Sitka', 'AKST9AKDT,M3.2.0,M11.1.0' },
{ 'America/St Barthelemy', 'AST4' },
{ 'America/St Johns', 'NST3:30NDT,M3.2.0,M11.1.0' },
@@ -204,16 +205,16 @@ TZ = {
{ 'Antarctica/Casey', '<+11>-11' },
{ 'Antarctica/Davis', '<+07>-7' },
{ 'Antarctica/DumontDUrville', '<+10>-10' },
- { 'Antarctica/Macquarie', 'MIST-11' },
+ { 'Antarctica/Macquarie', '<+11>-11' },
{ 'Antarctica/Mawson', '<+05>-5' },
{ 'Antarctica/McMurdo', 'NZST-12NZDT,M9.5.0,M4.1.0/3' },
- { 'Antarctica/Palmer', 'CLT4CLST,M8.2.6/24,M5.2.6/24' },
+ { 'Antarctica/Palmer', '<-03>3' },
{ 'Antarctica/Rothera', '<-03>3' },
{ 'Antarctica/Syowa', '<+03>-3' },
{ 'Antarctica/Troll', '<+00>0<+02>-2,M3.5.0/1,M10.5.0/3' },
{ 'Antarctica/Vostok', '<+06>-6' },
{ 'Arctic/Longyearbyen', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Asia/Aden', 'AST-3' },
+ { 'Asia/Aden', '<+03>-3' },
{ 'Asia/Almaty', '<+06>-6' },
{ 'Asia/Amman', 'EET-2EEST,M3.5.4/24,M10.5.5/1' },
{ 'Asia/Anadyr', '<+12>-12' },
@@ -221,102 +222,129 @@ TZ = {
{ 'Asia/Aqtobe', '<+05>-5' },
{ 'Asia/Ashgabat', '<+05>-5' },
{ 'Asia/Atyrau', '<+05>-5' },
- { 'Asia/Baghdad', 'AST-3' },
- { 'Asia/Bahrain', 'AST-3' },
+ { 'Asia/Baghdad', '<+03>-3' },
+ { 'Asia/Bahrain', '<+03>-3' },
{ 'Asia/Baku', '<+04>-4' },
- { 'Asia/Bangkok', 'ICT-7' },
+ { 'Asia/Bangkok', '<+07>-7' },
{ 'Asia/Barnaul', '<+07>-7' },
{ 'Asia/Beirut', 'EET-2EEST,M3.5.0/0,M10.5.0/0' },
{ 'Asia/Bishkek', '<+06>-6' },
- { 'Asia/Brunei', 'BNT-8' },
+ { 'Asia/Brunei', '<+08>-8' },
{ 'Asia/Chita', '<+09>-9' },
- { 'Asia/Choibalsan', 'CHOT-8CHOST,M3.5.6,M9.5.6/0' },
+ { 'Asia/Choibalsan', '<+08>-8' },
{ 'Asia/Colombo', '<+0530>-5:30' },
{ 'Asia/Damascus', 'EET-2EEST,M3.5.5/0,M10.5.5/0' },
- { 'Asia/Dhaka', 'BDT-6' },
- { 'Asia/Dili', 'TLT-9' },
- { 'Asia/Dubai', 'GST-4' },
+ { 'Asia/Dhaka', '<+06>-6' },
+ { 'Asia/Dili', '<+09>-9' },
+ { 'Asia/Dubai', '<+04>-4' },
{ 'Asia/Dushanbe', '<+05>-5' },
{ 'Asia/Famagusta', '<+03>-3' },
{ 'Asia/Gaza', 'EET-2EEST,M3.5.6/1,M10.5.6/1' },
{ 'Asia/Hebron', 'EET-2EEST,M3.5.6/1,M10.5.6/1' },
- { 'Asia/Ho Chi Minh', 'ICT-7' },
+ { 'Asia/Ho Chi Minh', '<+07>-7' },
{ 'Asia/Hong Kong', 'HKT-8' },
- { 'Asia/Hovd', 'HOVT-7HOVST,M3.5.6,M9.5.6/0' },
+ { 'Asia/Hovd', '<+07>-7' },
{ 'Asia/Irkutsk', '<+08>-8' },
{ 'Asia/Jakarta', 'WIB-7' },
{ 'Asia/Jayapura', 'WIT-9' },
{ 'Asia/Jerusalem', 'IST-2IDT,M3.4.4/26,M10.5.0' },
- { 'Asia/Kabul', 'AFT-4:30' },
+ { 'Asia/Kabul', '<+0430>-4:30' },
{ 'Asia/Kamchatka', '<+12>-12' },
{ 'Asia/Karachi', 'PKT-5' },
- { 'Asia/Kathmandu', 'NPT-5:45' },
+ { 'Asia/Kathmandu', '<+0545>-5:45' },
{ 'Asia/Khandyga', '<+09>-9' },
{ 'Asia/Kolkata', 'IST-5:30' },
{ 'Asia/Krasnoyarsk', '<+07>-7' },
- { 'Asia/Kuala Lumpur', 'MYT-8' },
- { 'Asia/Kuching', 'MYT-8' },
- { 'Asia/Kuwait', 'AST-3' },
+ { 'Asia/Kuala Lumpur', '<+08>-8' },
+ { 'Asia/Kuching', '<+08>-8' },
+ { 'Asia/Kuwait', '<+03>-3' },
{ 'Asia/Macau', 'CST-8' },
{ 'Asia/Magadan', '<+11>-11' },
{ 'Asia/Makassar', 'WITA-8' },
- { 'Asia/Manila', 'PHT-8' },
- { 'Asia/Muscat', 'GST-4' },
+ { 'Asia/Manila', '<+08>-8' },
+ { 'Asia/Muscat', '<+04>-4' },
{ 'Asia/Nicosia', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
{ 'Asia/Novokuznetsk', '<+07>-7' },
{ 'Asia/Novosibirsk', '<+07>-7' },
{ 'Asia/Omsk', '<+06>-6' },
{ 'Asia/Oral', '<+05>-5' },
- { 'Asia/Phnom Penh', 'ICT-7' },
+ { 'Asia/Phnom Penh', '<+07>-7' },
{ 'Asia/Pontianak', 'WIB-7' },
{ 'Asia/Pyongyang', 'KST-8:30' },
- { 'Asia/Qatar', 'AST-3' },
+ { 'Asia/Qatar', '<+03>-3' },
{ 'Asia/Qyzylorda', '<+06>-6' },
- { 'Asia/Riyadh', 'AST-3' },
+ { 'Asia/Riyadh', '<+03>-3' },
{ 'Asia/Sakhalin', '<+11>-11' },
{ 'Asia/Samarkand', '<+05>-5' },
{ 'Asia/Seoul', 'KST-9' },
{ 'Asia/Shanghai', 'CST-8' },
- { 'Asia/Singapore', 'SGT-8' },
+ { 'Asia/Singapore', '<+08>-8' },
{ 'Asia/Srednekolymsk', '<+11>-11' },
{ 'Asia/Taipei', 'CST-8' },
{ 'Asia/Tashkent', '<+05>-5' },
{ 'Asia/Tbilisi', '<+04>-4' },
- { 'Asia/Tehran', 'IRST-3:30IRDT,J80/0,J264/0' },
- { 'Asia/Thimphu', 'BTT-6' },
+ { 'Asia/Tehran', '<+0330>-3:30<+0430>,J80/0,J264/0' },
+ { 'Asia/Thimphu', '<+06>-6' },
{ 'Asia/Tokyo', 'JST-9' },
{ 'Asia/Tomsk', '<+07>-7' },
- { 'Asia/Ulaanbaatar', 'ULAT-8ULAST,M3.5.6,M9.5.6/0' },
- { 'Asia/Urumqi', 'XJT-6' },
+ { 'Asia/Ulaanbaatar', '<+08>-8' },
+ { 'Asia/Urumqi', '<+06>-6' },
{ 'Asia/Ust-Nera', '<+10>-10' },
- { 'Asia/Vientiane', 'ICT-7' },
+ { 'Asia/Vientiane', '<+07>-7' },
{ 'Asia/Vladivostok', '<+10>-10' },
{ 'Asia/Yakutsk', '<+09>-9' },
- { 'Asia/Yangon', 'MMT-6:30' },
+ { 'Asia/Yangon', '<+0630>-6:30' },
{ 'Asia/Yekaterinburg', '<+05>-5' },
{ 'Asia/Yerevan', '<+04>-4' },
- { 'Atlantic/Azores', 'AZOT1AZOST,M3.5.0/0,M10.5.0/1' },
+ { 'Atlantic/Azores', '<-01>1<+00>,M3.5.0/0,M10.5.0/1' },
{ 'Atlantic/Bermuda', 'AST4ADT,M3.2.0,M11.1.0' },
{ 'Atlantic/Canary', 'WET0WEST,M3.5.0/1,M10.5.0' },
- { 'Atlantic/Cape Verde', 'CVT1' },
+ { 'Atlantic/Cape Verde', '<-01>1' },
{ 'Atlantic/Faroe', 'WET0WEST,M3.5.0/1,M10.5.0' },
{ 'Atlantic/Madeira', 'WET0WEST,M3.5.0/1,M10.5.0' },
{ 'Atlantic/Reykjavik', 'GMT0' },
- { 'Atlantic/South Georgia', 'GST2' },
+ { 'Atlantic/South Georgia', '<-02>2' },
{ 'Atlantic/St Helena', 'GMT0' },
- { 'Atlantic/Stanley', 'FKST3' },
+ { 'Atlantic/Stanley', '<-03>3' },
{ 'Australia/Adelaide', 'ACST-9:30ACDT,M10.1.0,M4.1.0/3' },
{ 'Australia/Brisbane', 'AEST-10' },
{ 'Australia/Broken Hill', 'ACST-9:30ACDT,M10.1.0,M4.1.0/3' },
{ 'Australia/Currie', 'AEST-10AEDT,M10.1.0,M4.1.0/3' },
{ 'Australia/Darwin', 'ACST-9:30' },
- { 'Australia/Eucla', 'ACWST-8:45' },
+ { 'Australia/Eucla', '<+0845>-8:45' },
{ 'Australia/Hobart', 'AEST-10AEDT,M10.1.0,M4.1.0/3' },
{ 'Australia/Lindeman', 'AEST-10' },
- { 'Australia/Lord Howe', 'LHST-10:30LHDT-11,M10.1.0,M4.1.0' },
+ { 'Australia/Lord Howe', '<+1030>-10:30<+11>-11,M10.1.0,M4.1.0' },
{ 'Australia/Melbourne', 'AEST-10AEDT,M10.1.0,M4.1.0/3' },
{ 'Australia/Perth', 'AWST-8' },
{ 'Australia/Sydney', 'AEST-10AEDT,M10.1.0,M4.1.0/3' },
+ { 'Etc/GMT', 'GMT0' },
+ { 'Etc/GMT+1', '<-01>1' },
+ { 'Etc/GMT+10', '<-10>10' },
+ { 'Etc/GMT+11', '<-11>11' },
+ { 'Etc/GMT+12', '<-12>12' },
+ { 'Etc/GMT+2', '<-02>2' },
+ { 'Etc/GMT+3', '<-03>3' },
+ { 'Etc/GMT+4', '<-04>4' },
+ { 'Etc/GMT+5', '<-05>5' },
+ { 'Etc/GMT+6', '<-06>6' },
+ { 'Etc/GMT+7', '<-07>7' },
+ { 'Etc/GMT+8', '<-08>8' },
+ { 'Etc/GMT+9', '<-09>9' },
+ { 'Etc/GMT-1', '<+01>-1' },
+ { 'Etc/GMT-10', '<+10>-10' },
+ { 'Etc/GMT-11', '<+11>-11' },
+ { 'Etc/GMT-12', '<+12>-12' },
+ { 'Etc/GMT-13', '<+13>-13' },
+ { 'Etc/GMT-14', '<+14>-14' },
+ { 'Etc/GMT-2', '<+02>-2' },
+ { 'Etc/GMT-3', '<+03>-3' },
+ { 'Etc/GMT-4', '<+04>-4' },
+ { 'Etc/GMT-5', '<+05>-5' },
+ { 'Etc/GMT-6', '<+06>-6' },
+ { 'Etc/GMT-7', '<+07>-7' },
+ { 'Etc/GMT-8', '<+08>-8' },
+ { 'Etc/GMT-9', '<+09>-9' },
{ 'Europe/Amsterdam', 'CET-1CEST,M3.5.0,M10.5.0/3' },
{ 'Europe/Andorra', 'CET-1CEST,M3.5.0,M10.5.0/3' },
{ 'Europe/Astrakhan', '<+04>-4' },
@@ -378,53 +406,52 @@ TZ = {
{ 'Europe/Zaporozhye', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
{ 'Europe/Zurich', 'CET-1CEST,M3.5.0,M10.5.0/3' },
{ 'Indian/Antananarivo', 'EAT-3' },
- { 'Indian/Chagos', 'IOT-6' },
- { 'Indian/Christmas', 'CXT-7' },
- { 'Indian/Cocos', 'CCT-6:30' },
+ { 'Indian/Chagos', '<+06>-6' },
+ { 'Indian/Christmas', '<+07>-7' },
+ { 'Indian/Cocos', '<+0630>-6:30' },
{ 'Indian/Comoro', 'EAT-3' },
{ 'Indian/Kerguelen', '<+05>-5' },
- { 'Indian/Mahe', 'SCT-4' },
- { 'Indian/Maldives', 'MVT-5' },
- { 'Indian/Mauritius', 'MUT-4' },
+ { 'Indian/Mahe', '<+04>-4' },
+ { 'Indian/Maldives', '<+05>-5' },
+ { 'Indian/Mauritius', '<+04>-4' },
{ 'Indian/Mayotte', 'EAT-3' },
- { 'Indian/Reunion', 'RET-4' },
- { 'Pacific/Apia', 'WSST-13WSDT,M9.5.0/3,M4.1.0/4' },
+ { 'Indian/Reunion', '<+04>-4' },
+ { 'Pacific/Apia', '<+13>-13<+14>,M9.5.0/3,M4.1.0/4' },
{ 'Pacific/Auckland', 'NZST-12NZDT,M9.5.0,M4.1.0/3' },
- { 'Pacific/Bougainville', 'BST-11' },
- { 'Pacific/Chatham', 'CHAST-12:45CHADT,M9.5.0/2:45,M4.1.0/3:45' },
- { 'Pacific/Chuuk', 'CHUT-10' },
- { 'Pacific/Easter', 'EAST6EASST,M8.2.6/22,M5.2.6/22' },
- { 'Pacific/Efate', 'VUT-11' },
- { 'Pacific/Enderbury', 'PHOT-13' },
- { 'Pacific/Fakaofo', 'TKT-13' },
- { 'Pacific/Fiji', 'FJT-12FJST,M11.1.0,M1.3.0/3' },
- { 'Pacific/Funafuti', 'TVT-12' },
- { 'Pacific/Galapagos', 'GALT6' },
- { 'Pacific/Gambier', 'GAMT9' },
- { 'Pacific/Guadalcanal', 'SBT-11' },
+ { 'Pacific/Bougainville', '<+11>-11' },
+ { 'Pacific/Chatham', '<+1245>-12:45<+1345>,M9.5.0/2:45,M4.1.0/3:45' },
+ { 'Pacific/Chuuk', '<+10>-10' },
+ { 'Pacific/Easter', '<-06>6<-05>,M8.2.6/22,M5.2.6/22' },
+ { 'Pacific/Efate', '<+11>-11' },
+ { 'Pacific/Enderbury', '<+13>-13' },
+ { 'Pacific/Fakaofo', '<+13>-13' },
+ { 'Pacific/Fiji', '<+12>-12<+13>,M11.1.0,M1.3.0/3' },
+ { 'Pacific/Funafuti', '<+12>-12' },
+ { 'Pacific/Galapagos', '<-06>6' },
+ { 'Pacific/Gambier', '<-09>9' },
+ { 'Pacific/Guadalcanal', '<+11>-11' },
{ 'Pacific/Guam', 'ChST-10' },
{ 'Pacific/Honolulu', 'HST10' },
- { 'Pacific/Johnston', 'HST10' },
- { 'Pacific/Kiritimati', 'LINT-14' },
- { 'Pacific/Kosrae', 'KOST-11' },
- { 'Pacific/Kwajalein', 'MHT-12' },
- { 'Pacific/Majuro', 'MHT-12' },
- { 'Pacific/Marquesas', 'MART9:30' },
+ { 'Pacific/Kiritimati', '<+14>-14' },
+ { 'Pacific/Kosrae', '<+11>-11' },
+ { 'Pacific/Kwajalein', '<+12>-12' },
+ { 'Pacific/Majuro', '<+12>-12' },
+ { 'Pacific/Marquesas', '<-0930>9:30' },
{ 'Pacific/Midway', 'SST11' },
- { 'Pacific/Nauru', 'NRT-12' },
- { 'Pacific/Niue', 'NUT11' },
- { 'Pacific/Norfolk', 'NFT-11' },
- { 'Pacific/Noumea', 'NCT-11' },
+ { 'Pacific/Nauru', '<+12>-12' },
+ { 'Pacific/Niue', '<-11>11' },
+ { 'Pacific/Norfolk', '<+11>-11' },
+ { 'Pacific/Noumea', '<+11>-11' },
{ 'Pacific/Pago Pago', 'SST11' },
- { 'Pacific/Palau', 'PWT-9' },
- { 'Pacific/Pitcairn', 'PST8' },
- { 'Pacific/Pohnpei', 'PONT-11' },
- { 'Pacific/Port Moresby', 'PGT-10' },
- { 'Pacific/Rarotonga', 'CKT10' },
+ { 'Pacific/Palau', '<+09>-9' },
+ { 'Pacific/Pitcairn', '<-08>8' },
+ { 'Pacific/Pohnpei', '<+11>-11' },
+ { 'Pacific/Port Moresby', '<+10>-10' },
+ { 'Pacific/Rarotonga', '<-10>10' },
{ 'Pacific/Saipan', 'ChST-10' },
- { 'Pacific/Tahiti', 'TAHT10' },
- { 'Pacific/Tarawa', 'GILT-12' },
+ { 'Pacific/Tahiti', '<-10>10' },
+ { 'Pacific/Tarawa', '<+12>-12' },
{ 'Pacific/Tongatapu', '<+13>-13<+14>,M11.1.0,M1.3.0/3' },
- { 'Pacific/Wake', 'WAKT-12' },
- { 'Pacific/Wallis', 'WFT-12' },
+ { 'Pacific/Wake', '<+12>-12' },
+ { 'Pacific/Wallis', '<+12>-12' },
}
diff --git a/modules/luci-base/luasrc/sys/zoneinfo/tzoffset.lua b/modules/luci-base/luasrc/sys/zoneinfo/tzoffset.lua
index e5da7c6442..cf5afeb9d8 100644
--- a/modules/luci-base/luasrc/sys/zoneinfo/tzoffset.lua
+++ b/modules/luci-base/luasrc/sys/zoneinfo/tzoffset.lua
@@ -16,123 +16,30 @@ OFFSET = {
akst = -32400, -- AKST
akdt = -28800, -- AKDT
ast = -14400, -- AST
- brt = -10800, -- BRT
- art = -10800, -- ART
- pyt = -14400, -- PYT
- pyst = -10800, -- PYST
est = -18000, -- EST
cst = -21600, -- CST
cdt = -18000, -- CDT
- amt = -14400, -- AMT
- cot = -18000, -- COT
mst = -25200, -- MST
mdt = -21600, -- MDT
- vet = -14400, -- VET
- gft = -10800, -- GFT
pst = -28800, -- PST
pdt = -25200, -- PDT
- act = -18000, -- ACT
- wgt = -10800, -- WGT
- wgst = -7200, -- WGST
- ect = -18000, -- ECT
- gyt = -14400, -- GYT
- bot = -14400, -- BOT
- pet = -18000, -- PET
- pmst = -10800, -- PMST
- pmdt = -7200, -- PMDT
- uyt = -10800, -- UYT
- fnt = -7200, -- FNT
- srt = -10800, -- SRT
- clt = -14400, -- CLT
- clst = -10800, -- CLST
- egt = -3600, -- EGT
- egst = 0, -- EGST
nst = -12600, -- NST
ndt = -9000, -- NDT
- mist = 39600, -- MIST
nzst = 43200, -- NZST
nzdt = 46800, -- NZDT
- ict = 25200, -- ICT
- bnt = 28800, -- BNT
- chot = 28800, -- CHOT
- chost = 32400, -- CHOST
- bdt = 21600, -- BDT
- tlt = 32400, -- TLT
- gst = 14400, -- GST
hkt = 28800, -- HKT
- hovt = 25200, -- HOVT
- hovst = 28800, -- HOVST
wib = 25200, -- WIB
wit = 32400, -- WIT
ist = 7200, -- IST
idt = 10800, -- IDT
- aft = 16200, -- AFT
pkt = 18000, -- PKT
- npt = 20700, -- NPT
- myt = 28800, -- MYT
wita = 28800, -- WITA
- pht = 28800, -- PHT
kst = 30600, -- KST
- sgt = 28800, -- SGT
- irst = 12600, -- IRST
- irdt = 16200, -- IRDT
- btt = 21600, -- BTT
jst = 32400, -- JST
- ulat = 28800, -- ULAT
- ulast = 32400, -- ULAST
- xjt = 21600, -- XJT
- mmt = 23400, -- MMT
- azot = -3600, -- AZOT
- azost = 0, -- AZOST
- cvt = -3600, -- CVT
- fkst = -10800, -- FKST
acst = 34200, -- ACST
acdt = 37800, -- ACDT
aest = 36000, -- AEST
- acwst = 31500, -- ACWST
- lhst = 37800, -- LHST
- lhdt = 39600, -- LHDT
awst = 28800, -- AWST
msk = 10800, -- MSK
- iot = 21600, -- IOT
- cxt = 25200, -- CXT
- cct = 23400, -- CCT
- sct = 14400, -- SCT
- mvt = 18000, -- MVT
- mut = 14400, -- MUT
- ret = 14400, -- RET
- wsst = 46800, -- WSST
- wsdt = 50400, -- WSDT
- bst = 39600, -- BST
- chast = 45900, -- CHAST
- chadt = 49500, -- CHADT
- chut = 36000, -- CHUT
- east = -21600, -- EAST
- easst = -18000, -- EASST
- vut = 39600, -- VUT
- phot = 46800, -- PHOT
- tkt = 46800, -- TKT
- fjt = 43200, -- FJT
- fjst = 46800, -- FJST
- tvt = 43200, -- TVT
- galt = -21600, -- GALT
- gamt = -32400, -- GAMT
- sbt = 39600, -- SBT
- lint = 50400, -- LINT
- kost = 39600, -- KOST
- mht = 43200, -- MHT
- mart = -34200, -- MART
sst = -39600, -- SST
- nrt = 43200, -- NRT
- nut = -39600, -- NUT
- nft = 39600, -- NFT
- nct = 39600, -- NCT
- pwt = 32400, -- PWT
- pont = 39600, -- PONT
- pgt = 36000, -- PGT
- ckt = -36000, -- CKT
- taht = -36000, -- TAHT
- gilt = 43200, -- GILT
- wakt = 43200, -- WAKT
- wft = 43200, -- WFT
}
diff --git a/modules/luci-base/luasrc/tools/status.lua b/modules/luci-base/luasrc/tools/status.lua
index b531393d0f..95ff46df15 100644
--- a/modules/luci-base/luasrc/tools/status.lua
+++ b/modules/luci-base/luasrc/tools/status.lua
@@ -74,9 +74,19 @@ local function dhcp_leases_common(family)
hostname = (name ~= "-") and name
}
elseif ip and iaid == "ipv4" and family == 4 then
+ local mac, mac1, mac2, mac3, mac4, mac5, mac6
+ if duid and type(duid) == "string" then
+ mac1, mac2, mac3, mac4, mac5, mac6 = duid:match("^(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)$")
+ end
+ if not (mac1 and mac2 and mac3 and mac4 and mac5 and mac6) then
+ mac = "FF:FF:FF:FF:FF:FF"
+ else
+ mac = mac1..":"..mac2..":"..mac3..":"..mac4..":"..mac5..":"..mac6
+ end
rv[#rv+1] = {
expires = (expire >= 0) and os.difftime(expire, os.time()),
macaddr = duid,
+ macaddr = mac:lower(),
ipaddr = ip,
hostname = (name ~= "-") and name
}
diff --git a/modules/luci-base/luasrc/view/cbi/firewall_zoneforwards.htm b/modules/luci-base/luasrc/view/cbi/firewall_zoneforwards.htm
index 2a433b5696..546fd8e85a 100644
--- a/modules/luci-base/luasrc/view/cbi/firewall_zoneforwards.htm
+++ b/modules/luci-base/luasrc/view/cbi/firewall_zoneforwards.htm
@@ -43,11 +43,12 @@
&#160;&#8658;&#160;
<% for _, fwd in ipairs(zone:get_forwardings_by("src")) do
fz = fwd:dest_zone()
- empty = false %>
+ if fz then
+ empty = false %>
<label class="zonebadge" style="background-color:<%=fz:get_color()%>">
<strong><%=fz:name()%></strong>
</label>&#160;
- <% end %>
+ <% end end %>
<% if empty then %>
<label class="zonebadge zonebadge-empty">
<strong><%=zone:forward():upper()%></strong>