diff options
Diffstat (limited to 'libs')
-rw-r--r-- | libs/luci-lib-base/luasrc/http.lua | 465 | ||||
-rw-r--r-- | libs/luci-lib-base/luasrc/util.lua | 27 | ||||
-rw-r--r-- | libs/luci-lib-httpprotoutils/luasrc/http/mime.lua | 3 | ||||
-rw-r--r-- | libs/luci-lib-nixio/Makefile | 40 | ||||
-rw-r--r-- | libs/luci-lib-px5g/Makefile | 4 | ||||
-rw-r--r-- | libs/rpcd-mod-luci/Makefile | 3 | ||||
-rw-r--r-- | libs/rpcd-mod-luci/src/luci.c | 211 |
7 files changed, 121 insertions, 632 deletions
diff --git a/libs/luci-lib-base/luasrc/http.lua b/libs/luci-lib-base/luasrc/http.lua index 20b55f2854..882b71c8f7 100644 --- a/libs/luci-lib-base/luasrc/http.lua +++ b/libs/luci-lib-base/luasrc/http.lua @@ -6,234 +6,66 @@ local util = require "luci.util" local coroutine = require "coroutine" local table = require "table" local lhttp = require "lucihttp" -local nixio = require "nixio" -local ltn12 = require "luci.ltn12" -local table, ipairs, pairs, type, tostring, tonumber, error = - table, ipairs, pairs, type, tostring, tonumber, error +local L, table, ipairs, pairs, type, error = _G.L, table, ipairs, pairs, type, error module "luci.http" HTTP_MAX_CONTENT = 1024*100 -- 100 kB maximum content size -context = util.threadlocal() - -Request = util.class() -function Request.__init__(self, env, sourcein, sinkerr) - self.input = sourcein - self.error = sinkerr - - - -- File handler nil by default to let .content() work - self.filehandler = nil - - -- HTTP-Message table - self.message = { - env = env, - headers = {}, - params = urldecode_params(env.QUERY_STRING or ""), - } - - self.parsed_input = false -end - -function Request.formvalue(self, name, noparse) - if not noparse and not self.parsed_input then - self:_parse_input() - end - - if name then - return self.message.params[name] - else - return self.message.params - end -end - -function Request.formvaluetable(self, prefix) - local vals = {} - prefix = prefix and prefix .. "." or "." - - if not self.parsed_input then - self:_parse_input() - end - - local void = self.message.params[nil] - for k, v in pairs(self.message.params) do - if k:find(prefix, 1, true) == 1 then - vals[k:sub(#prefix + 1)] = tostring(v) - end - end - - return vals -end - -function Request.content(self) - if not self.parsed_input then - self:_parse_input() - end - - return self.message.content, self.message.content_length -end - -function Request.getcookie(self, name) - return lhttp.header_attribute("cookie; " .. (self:getenv("HTTP_COOKIE") or ""), name) -end - -function Request.getenv(self, name) - if name then - return self.message.env[name] - else - return self.message.env - end -end - -function Request.setfilehandler(self, callback) - self.filehandler = callback - - if not self.parsed_input then - return - end - - -- If input has already been parsed then uploads are stored as unlinked - -- temporary files pointed to by open file handles in the parameter - -- value table. Loop all params, and invoke the file callback for any - -- param with an open file handle. - local name, value - for name, value in pairs(self.message.params) do - if type(value) == "table" then - while value.fd do - local data = value.fd:read(1024) - local eof = (not data or data == "") - - callback(value, data, eof) - - if eof then - value.fd:close() - value.fd = nil - end - end - end - end -end - -function Request._parse_input(self) - parse_message_body( - self.input, - self.message, - self.filehandler - ) - self.parsed_input = true -end - function close() - if not context.eoh then - context.eoh = true - coroutine.yield(3) - end - - if not context.closed then - context.closed = true - coroutine.yield(5) - end + L.http:close() end function content() - return context.request:content() + return L.http:content() end function formvalue(name, noparse) - return context.request:formvalue(name, noparse) + return L.http:formvalue(name, noparse) end function formvaluetable(prefix) - return context.request:formvaluetable(prefix) + return L.http:formvaluetable(prefix) end function getcookie(name) - return context.request:getcookie(name) + return L.http:getcookie(name) end -- or the environment table itself. function getenv(name) - return context.request:getenv(name) + return L.http:getenv(name) end function setfilehandler(callback) - return context.request:setfilehandler(callback) + return L.http:setfilehandler(callback) end function header(key, value) - if not context.headers then - context.headers = {} - end - context.headers[key:lower()] = value - coroutine.yield(2, key, value) + L.http:header(key, value) end function prepare_content(mime) - if not context.headers or not context.headers["content-type"] then - if mime == "application/xhtml+xml" then - if not getenv("HTTP_ACCEPT") or - not getenv("HTTP_ACCEPT"):find("application/xhtml+xml", nil, true) then - mime = "text/html; charset=UTF-8" - end - header("Vary", "Accept") - end - header("Content-Type", mime) - end + L.http:prepare_content(mime) end function source() - return context.request.input + return L.http.input end function status(code, message) - code = code or 200 - message = message or "OK" - context.status = code - coroutine.yield(1, code, message) + L.http:status(code, message) end -- This function is as a valid LTN12 sink. -- If the content chunk is nil this function will automatically invoke close. function write(content, src_err) - if not content then - if src_err then - error(src_err) - else - close() - end - return true - elseif #content == 0 then - return true - else - if not context.eoh then - if not context.status then - status() - end - if not context.headers or not context.headers["content-type"] then - header("Content-Type", "text/html; charset=utf-8") - end - if not context.headers["cache-control"] then - 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) - end - coroutine.yield(4, content) - return true + if src_err then + error(src_err) end + + return L.print(content) end function splice(fd, size) @@ -241,10 +73,7 @@ function splice(fd, size) end function redirect(url) - if url == "" then url = "/" end - status(302, "Found") - header("Location", url) - close() + L.http:redirect(url) end function build_querystring(q) @@ -266,35 +95,7 @@ urldecode = util.urldecode urlencode = util.urlencode function write_json(x) - util.serialize_json(x, write) -end - --- from given url or string. Returns a table with urldecoded values. --- Simple parameters are stored as string values associated with the parameter --- name within the table. Parameters with multiple values are stored as array --- containing the corresponding values. -function urldecode_params(url, tbl) - local parser, name - local params = tbl or { } - - parser = lhttp.urlencoded_parser(function (what, buffer, length) - if what == parser.TUPLE then - name, value = nil, nil - elseif what == parser.NAME then - name = lhttp.urldecode(buffer) - elseif what == parser.VALUE and name then - params[name] = lhttp.urldecode(buffer) or "" - end - - return true - end) - - if parser then - parser:parse((url or ""):match("[^?]*$")) - parser:parse(nil) - end - - return params + L.printf('%J', x) end -- separated by "&". Tables are encoded as parameters with multiple values by @@ -332,223 +133,13 @@ function urlencode_params(tbl) return table.concat(enc, "") end --- Content-Type. Stores all extracted data associated with its parameter name --- 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 fed with the --- file contents chunk by chunk and only the extracted file name is stored --- within the params table. The callback function will be called subsequently --- with three arguments: --- o Table containing decoded (name, file) and raw (headers) mime header data --- o String value containing a chunk of the file data --- o Boolean which indicates whether the current chunk is the last one (eof) -function mimedecode_message_body(src, msg, file_cb) - local parser, header, field - local len, maxlen = 0, tonumber(msg.env.CONTENT_LENGTH or nil) - - parser, err = lhttp.multipart_parser(msg.env.CONTENT_TYPE, function (what, buffer, length) - if what == parser.PART_INIT then - field = { } - - elseif what == parser.HEADER_NAME then - header = buffer:lower() - - elseif what == parser.HEADER_VALUE and header then - if header:lower() == "content-disposition" and - lhttp.header_attribute(buffer, nil) == "form-data" - then - field.name = lhttp.header_attribute(buffer, "name") - field.file = lhttp.header_attribute(buffer, "filename") - field[1] = field.file - end - - if field.headers then - field.headers[header] = buffer - else - field.headers = { [header] = buffer } - end - - elseif what == parser.PART_BEGIN then - return not field.file - - elseif what == parser.PART_DATA and field.name and length > 0 then - if field.file then - if file_cb then - file_cb(field, buffer, false) - msg.params[field.name] = msg.params[field.name] or field - else - if not field.fd then - field.fd = nixio.mkstemp(field.name) - end - - if field.fd then - field.fd:write(buffer) - msg.params[field.name] = msg.params[field.name] or field - end - end - else - field.value = buffer - end - - elseif what == parser.PART_END and field.name then - if field.file and msg.params[field.name] then - if file_cb then - file_cb(field, "", true) - elseif field.fd then - field.fd:seek(0, "set") - end - else - local val = msg.params[field.name] - - if type(val) == "table" then - val[#val+1] = field.value or "" - elseif val ~= nil then - msg.params[field.name] = { val, field.value or "" } - else - msg.params[field.name] = field.value or "" - end - end - - field = nil - - elseif what == parser.ERROR then - err = buffer - end - - return true - end, HTTP_MAX_CONTENT) - - return ltn12.pump.all(src, function (chunk) - len = len + (chunk and #chunk or 0) - - if maxlen and len > maxlen + 2 then - return nil, "Message body size exceeds Content-Length" - end - - if not parser or not parser:parse(chunk) then - return nil, err - end - - return true - end) -end - --- Content-Type. Stores all extracted data associated with its parameter name --- 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) - local err, name, value, parser - local len, maxlen = 0, tonumber(msg.env.CONTENT_LENGTH or nil) - - parser = lhttp.urlencoded_parser(function (what, buffer, length) - if what == parser.TUPLE then - name, value = nil, nil - elseif what == parser.NAME then - name = lhttp.urldecode(buffer, lhttp.DECODE_PLUS) - elseif what == parser.VALUE and name then - local val = msg.params[name] - - if type(val) == "table" then - val[#val+1] = lhttp.urldecode(buffer, lhttp.DECODE_PLUS) or "" - elseif val ~= nil then - msg.params[name] = { val, lhttp.urldecode(buffer, lhttp.DECODE_PLUS) or "" } - else - msg.params[name] = lhttp.urldecode(buffer, lhttp.DECODE_PLUS) or "" - end - elseif what == parser.ERROR then - err = buffer - end - - return true - end, HTTP_MAX_CONTENT) - - return ltn12.pump.all(src, function (chunk) - len = len + (chunk and #chunk or 0) - - if maxlen and len > maxlen + 2 then - return nil, "Message body size exceeds Content-Length" - elseif len > HTTP_MAX_CONTENT then - return nil, "Message body size exceeds maximum allowed length" - end - - if not parser or not parser:parse(chunk) then - return nil, err - end - - return true - end) -end - --- This function will examine the Content-Type within the given message object --- to select the appropriate content decoder. --- Currently the application/x-www-urlencoded and application/form-data --- mime types are supported. If the encountered content encoding can't be --- handled then the whole message body will be stored unaltered as "content" --- property within the given message object. -function parse_message_body(src, msg, filecb) - if msg.env.CONTENT_LENGTH or msg.env.REQUEST_METHOD == "POST" then - local ctype = lhttp.header_attribute(msg.env.CONTENT_TYPE, nil) - - -- Is it multipart/mime ? - if ctype == "multipart/form-data" then - return mimedecode_message_body(src, msg, filecb) - - -- Is it application/x-www-form-urlencoded ? - elseif ctype == "application/x-www-form-urlencoded" then - return urldecode_message_body(src, msg) - - end - - -- Unhandled encoding - -- If a file callback is given then feed it chunk by chunk, else - -- store whole buffer in message.content - local sink - - -- If we have a file callback then feed it - if type(filecb) == "function" then - local meta = { - name = "raw", - encoding = msg.env.CONTENT_TYPE - } - sink = function( chunk ) - if chunk then - return filecb(meta, chunk, false) - else - return filecb(meta, nil, true) - end - end - -- ... else append to .content - else - msg.content = "" - msg.content_length = 0 - - sink = function( chunk ) - if chunk then - if ( msg.content_length + #chunk ) <= HTTP_MAX_CONTENT then - msg.content = msg.content .. chunk - msg.content_length = msg.content_length + #chunk - return true - else - return nil, "POST data exceeds maximum allowed length" - end - end - return true - end - end - - -- Pump data... - while true do - local ok, err = ltn12.pump.step( src, sink ) - - if not ok and err then - return nil, err - elseif not ok then -- eof - return true - end - end - - return true - end - - return false -end +context = { + request = { + formvalue = function(self, ...) return formvalue(...) end; + formvaluetable = function(self, ...) return formvaluetable(...) end; + content = function(self, ...) return content(...) end; + getcookie = function(self, ...) return getcookie(...) end; + setfilehandler = function(self, ...) return setfilehandler(...) end; + message = L and L.http.message + } +} diff --git a/libs/luci-lib-base/luasrc/util.lua b/libs/luci-lib-base/luasrc/util.lua index 89757917ff..80013179aa 100644 --- a/libs/luci-lib-base/luasrc/util.lua +++ b/libs/luci-lib-base/luasrc/util.lua @@ -100,32 +100,8 @@ end -- Scope manipulation routines -- -coxpt = setmetatable({}, { __mode = "kv" }) - -local tl_meta = { - __mode = "k", - - __index = function(self, key) - local t = rawget(self, coxpt[coroutine.running()] - or coroutine.running() or 0) - return t and t[key] - end, - - __newindex = function(self, key, value) - local c = coxpt[coroutine.running()] or coroutine.running() or 0 - local r = rawget(self, c) - if not r then - rawset(self, c, { [key] = value }) - else - r[key] = value - end - end -} - --- the current active coroutine. A thread local store is private a table object --- whose values can't be accessed from outside of the running coroutine. function threadlocal(tbl) - return setmetatable(tbl or {}, tl_meta) + return tbl or {} end @@ -772,7 +748,6 @@ function coxpcall(f, err, ...) co = coroutine.create(newf) end coromap[co] = current - coxpt[co] = coxpt[current] or current or 0 return performResume(err, co, ...) end end diff --git a/libs/luci-lib-httpprotoutils/luasrc/http/mime.lua b/libs/luci-lib-httpprotoutils/luasrc/http/mime.lua index 0bcff8a36b..90176b5a77 100644 --- a/libs/luci-lib-httpprotoutils/luasrc/http/mime.lua +++ b/libs/luci-lib-httpprotoutils/luasrc/http/mime.lua @@ -45,10 +45,13 @@ MIME_TYPES = { ["mp3"] = "audio/mpeg"; ["ogg"] = "audio/x-vorbis+ogg"; ["wav"] = "audio/x-wav"; + ["aac"] = "audio/aac"; ["mpg"] = "video/mpeg"; ["mpeg"] = "video/mpeg"; ["avi"] = "video/x-msvideo"; + ["mov"] = "video/quicktime"; + ["mp4"] = "video/mp4"; } -- "application/octet-stream" if the extension is unknown. diff --git a/libs/luci-lib-nixio/Makefile b/libs/luci-lib-nixio/Makefile index 4e501b89ce..91715e41d3 100644 --- a/libs/luci-lib-nixio/Makefile +++ b/libs/luci-lib-nixio/Makefile @@ -7,48 +7,10 @@ include $(TOPDIR)/rules.mk LUCI_TITLE:=NIXIO POSIX library -LUCI_DEPENDS:=+PACKAGE_luci-lib-nixio_openssl:libopenssl +PACKAGE_luci-lib-nixio_cyassl:libcyassl +liblua +LUCI_DEPENDS:=+liblua PKG_LICENSE:=Apache-2.0 -define Package/luci-lib-nixio/config - choice - prompt "TLS Provider" - default PACKAGE_luci-lib-nixio_notls - - config PACKAGE_luci-lib-nixio_notls - bool "Disabled" - - config PACKAGE_luci-lib-nixio_axtls - bool "Builtin (axTLS)" - - config PACKAGE_luci-lib-nixio_cyassl - bool "CyaSSL" - select PACKAGE_libcyassl - - config PACKAGE_luci-lib-nixio_openssl - bool "OpenSSL" - select PACKAGE_libopenssl - endchoice -endef - -NIXIO_TLS:= - -ifneq ($(CONFIG_PACKAGE_luci-lib-nixio_axtls),) - NIXIO_TLS:=axtls -endif - -ifneq ($(CONFIG_PACKAGE_luci-lib-nixio_openssl),) - NIXIO_TLS:=openssl -endif - -ifneq ($(CONFIG_PACKAGE_luci-lib-nixio_cyassl),) - NIXIO_TLS:=cyassl - LUCI_CFLAGS+=-I$(STAGING_DIR)/usr/include/cyassl -endif - -MAKE_VARS += NIXIO_TLS="$(NIXIO_TLS)" - include ../../luci.mk # call BuildPackage - OpenWrt buildroot signature diff --git a/libs/luci-lib-px5g/Makefile b/libs/luci-lib-px5g/Makefile index eefee107e8..269dfeb7a8 100644 --- a/libs/luci-lib-px5g/Makefile +++ b/libs/luci-lib-px5g/Makefile @@ -7,9 +7,9 @@ include $(TOPDIR)/rules.mk LUCI_TITLE:=RSA/X.509 Key Generator (required for LuCId SSL support) -LUCI_DEPENDS:=+liblua +LUCI_DEPENDS:=+lua +luci-lib-nixio -PKG_USE_MIPS16:=0 +PKG_BUILD_FLAGS:=no-mips16 PKG_LICENSE:=LGPL-2.1 include ../../luci.mk diff --git a/libs/rpcd-mod-luci/Makefile b/libs/rpcd-mod-luci/Makefile index 7909d4a7b3..ece32a4cc9 100644 --- a/libs/rpcd-mod-luci/Makefile +++ b/libs/rpcd-mod-luci/Makefile @@ -7,7 +7,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=rpcd-mod-luci -PKG_VERSION:=20210614 +PKG_VERSION:=20230123 +PKG_RELEASE:=1 PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io> PKG_LICENSE:=Apache-2.0 diff --git a/libs/rpcd-mod-luci/src/luci.c b/libs/rpcd-mod-luci/src/luci.c index 131180a750..e21105d3c6 100644 --- a/libs/rpcd-mod-luci/src/luci.c +++ b/libs/rpcd-mod-luci/src/luci.c @@ -76,9 +76,12 @@ struct invoke_context { void *priv; }; -static const char **iw_modenames; +typedef const char * const iw_text_t; +static iw_text_t *iw_modenames, *iw_authnames, *iw_kmgmtnames, + *iw_ciphernames, *iw_htmodenames, *iw_80211names; static struct iwinfo_ops *(*iw_backend)(const char *); static void (*iw_close)(void); +static size_t (*iw_format_hwmodes)(int, char *, size_t); static void invoke_data_cb(struct ubus_request *req, int type, struct blob_attr *msg) @@ -788,13 +791,13 @@ rpc_luci_parse_network_device_sys(const char *name, struct ifaddrs *ifaddr) blobmsg_close_table(&blob, o2); o2 = blobmsg_open_table(&blob, "flags"); - blobmsg_add_u8(&blob, "up", ifa_flags & IFF_UP); - blobmsg_add_u8(&blob, "broadcast", ifa_flags & IFF_BROADCAST); - blobmsg_add_u8(&blob, "promisc", ifa_flags & IFF_PROMISC); - blobmsg_add_u8(&blob, "loopback", ifa_flags & IFF_LOOPBACK); - blobmsg_add_u8(&blob, "noarp", ifa_flags & IFF_NOARP); - blobmsg_add_u8(&blob, "multicast", ifa_flags & IFF_MULTICAST); - blobmsg_add_u8(&blob, "pointtopoint", ifa_flags & IFF_POINTOPOINT); + blobmsg_add_u8(&blob, "up", !!(ifa_flags & IFF_UP)); + blobmsg_add_u8(&blob, "broadcast", !!(ifa_flags & IFF_BROADCAST)); + blobmsg_add_u8(&blob, "promisc", !!(ifa_flags & IFF_PROMISC)); + blobmsg_add_u8(&blob, "loopback", !!(ifa_flags & IFF_LOOPBACK)); + blobmsg_add_u8(&blob, "noarp", !!(ifa_flags & IFF_NOARP)); + blobmsg_add_u8(&blob, "multicast", !!(ifa_flags & IFF_MULTICAST)); + blobmsg_add_u8(&blob, "pointtopoint", !!(ifa_flags & IFF_POINTOPOINT)); blobmsg_close_table(&blob, o2); o2 = blobmsg_open_table(&blob, "link"); @@ -884,6 +887,48 @@ iw_call_num(int (*method)(const char *, int *), const char *dev, blobmsg_add_u32(blob, field, val); } +static void +iw_lower(const char *src, char *dst, size_t len) +{ + size_t i; + + for (i = 0; *src && i < len; i++) + *dst++ = tolower(*src++); + + *dst = 0; +} + +static void +iw_add_bit_array(struct blob_buf *buf, const char *name, uint32_t bits, + iw_text_t values[], size_t len, bool lower, uint32_t zero) +{ + void *c; + size_t i; + char l[128]; + const char *v; + + if (!bits) + bits = zero; + + c = blobmsg_open_array(buf, name); + + for (i = 0; i < len; i++) + if (bits & 1 << i) + { + v = values[i]; + + if (lower) + { + iw_lower(v, l, strlen(values[i])); + v = l; + } + + blobmsg_add_string(buf, NULL, v); + } + + blobmsg_close_array(buf, c); +} + static bool rpc_luci_get_iwinfo(struct blob_buf *buf, const char *devname, bool phy_only) { @@ -894,8 +939,10 @@ static bool rpc_luci_get_iwinfo(struct blob_buf *buf, const char *devname, void *o, *o2, *a; glob_t paths; int nret, i; + char text[32]; - if (!iw_backend || !iw_close || !iw_modenames) { + if (!iw_backend || !iw_close || !iw_format_hwmodes || !iw_modenames || !iw_80211names || + !iw_htmodenames || !iw_authnames || !iw_kmgmtnames || !iw_ciphernames) { if (glob("/usr/lib/libiwinfo.so*", 0, NULL, &paths) != 0) return false; @@ -909,9 +956,16 @@ static bool rpc_luci_get_iwinfo(struct blob_buf *buf, const char *devname, iw_backend = dlsym(iwlib, "iwinfo_backend"); iw_close = dlsym(iwlib, "iwinfo_close"); + iw_format_hwmodes = dlsym(iwlib, "iwinfo_format_hwmodes"); iw_modenames = dlsym(iwlib, "IWINFO_OPMODE_NAMES"); - - if (!iw_backend || !iw_close || !iw_modenames) + iw_80211names = dlsym(iwlib, "IWINFO_80211_NAMES"); + iw_htmodenames = dlsym(iwlib, "IWINFO_HTMODE_NAMES"); + iw_authnames = dlsym(iwlib, "IWINFO_AUTH_NAMES"); + iw_kmgmtnames = dlsym(iwlib, "IWINFO_KMGMT_NAMES"); + iw_ciphernames = dlsym(iwlib, "IWINFO_CIPHER_NAMES"); + + if (!iw_backend || !iw_close || !iw_format_hwmodes || !iw_modenames || !iw_80211names || + !iw_htmodenames || !iw_authnames || !iw_kmgmtnames || !iw_ciphernames) return false; } @@ -933,67 +987,16 @@ static bool rpc_luci_get_iwinfo(struct blob_buf *buf, const char *devname, iw_call_num(iw->frequency_offset, devname, buf, "frequency_offset"); if (!iw->hwmodelist(devname, &nret)) { - a = blobmsg_open_array(buf, "hwmodes"); - - if (nret & IWINFO_80211_AX) - blobmsg_add_string(buf, NULL, "ax"); - - if (nret & IWINFO_80211_AC) - blobmsg_add_string(buf, NULL, "ac"); - - if (nret & IWINFO_80211_A) - blobmsg_add_string(buf, NULL, "a"); - - if (nret & IWINFO_80211_B) - blobmsg_add_string(buf, NULL, "b"); - - if (nret & IWINFO_80211_G) - blobmsg_add_string(buf, NULL, "g"); + iw_add_bit_array(buf, "hwmodes", nret, + iw_80211names, IWINFO_80211_COUNT, true, 0); - if (nret & IWINFO_80211_N) - blobmsg_add_string(buf, NULL, "n"); - - blobmsg_close_array(buf, a); + if (iw_format_hwmodes(nret, text, sizeof(text)) > 0) + blobmsg_add_string(buf, "hwmodes_text", text); } - if (!iw->htmodelist(devname, &nret)) { - a = blobmsg_open_array(buf, "htmodes"); - - if (nret & IWINFO_HTMODE_HT20) - blobmsg_add_string(buf, NULL, "HT20"); - - if (nret & IWINFO_HTMODE_HT40) - blobmsg_add_string(buf, NULL, "HT40"); - - if (nret & IWINFO_HTMODE_VHT20) - blobmsg_add_string(buf, NULL, "VHT20"); - - if (nret & IWINFO_HTMODE_VHT40) - blobmsg_add_string(buf, NULL, "VHT40"); - - if (nret & IWINFO_HTMODE_VHT80) - blobmsg_add_string(buf, NULL, "VHT80"); - - if (nret & IWINFO_HTMODE_VHT80_80) - blobmsg_add_string(buf, NULL, "VHT80+80"); - - if (nret & IWINFO_HTMODE_VHT160) - blobmsg_add_string(buf, NULL, "VHT160"); - - if (nret & IWINFO_HTMODE_HE20) - blobmsg_add_string(buf, NULL, "HE20"); - - if (nret & IWINFO_HTMODE_HE40) - blobmsg_add_string(buf, NULL, "HE40"); - - if (nret & IWINFO_HTMODE_HE80) - blobmsg_add_string(buf, NULL, "HE80"); - - if (nret & IWINFO_HTMODE_HE160) - blobmsg_add_string(buf, NULL, "HE160"); - - blobmsg_close_array(buf, a); - } + if (!iw->htmodelist(devname, &nret)) + iw_add_bit_array(buf, "htmodes", nret & ~IWINFO_HTMODE_NOHT, + iw_htmodenames, IWINFO_HTMODE_COUNT, false, 0); if (!iw->hardware_id(devname, (char *)&ids)) { o2 = blobmsg_open_table(buf, "hardware"); @@ -1028,17 +1031,10 @@ static bool rpc_luci_get_iwinfo(struct blob_buf *buf, const char *devname, if (crypto.enabled) { if (!crypto.wpa_version) { - a = blobmsg_open_array(buf, "wep"); - - if (crypto.auth_algs & IWINFO_AUTH_OPEN) - blobmsg_add_string(buf, NULL, "open"); - - if (crypto.auth_algs & IWINFO_AUTH_SHARED) - blobmsg_add_string(buf, NULL, "shared"); - - blobmsg_close_array(buf, a); - } - else { + iw_add_bit_array(buf, "wep", crypto.auth_algs, + iw_authnames, IWINFO_AUTH_COUNT, + true, 0); + } else { a = blobmsg_open_array(buf, "wpa"); for (nret = 1; nret <= 3; nret++) @@ -1047,55 +1043,16 @@ static bool rpc_luci_get_iwinfo(struct blob_buf *buf, const char *devname, blobmsg_close_array(buf, a); - a = blobmsg_open_array(buf, "authentication"); - - if (crypto.auth_suites & IWINFO_KMGMT_PSK) - blobmsg_add_string(buf, NULL, "psk"); - - if (crypto.auth_suites & IWINFO_KMGMT_8021x) - blobmsg_add_string(buf, NULL, "802.1x"); - - if (crypto.auth_suites & IWINFO_KMGMT_SAE) - blobmsg_add_string(buf, NULL, "sae"); - - if (crypto.auth_suites & IWINFO_KMGMT_OWE) - blobmsg_add_string(buf, NULL, "owe"); - - if (!crypto.auth_suites || - (crypto.auth_suites & IWINFO_KMGMT_NONE)) - blobmsg_add_string(buf, NULL, "none"); - - blobmsg_close_array(buf, a); + iw_add_bit_array(buf, "authentication", + crypto.auth_suites, + iw_kmgmtnames, IWINFO_KMGMT_COUNT, + true, IWINFO_KMGMT_NONE); } - a = blobmsg_open_array(buf, "ciphers"); - nret = crypto.pair_ciphers | crypto.group_ciphers; - - if (nret & IWINFO_CIPHER_WEP40) - blobmsg_add_string(buf, NULL, "wep-40"); - - if (nret & IWINFO_CIPHER_WEP104) - blobmsg_add_string(buf, NULL, "wep-104"); - - if (nret & IWINFO_CIPHER_TKIP) - blobmsg_add_string(buf, NULL, "tkip"); - - if (nret & IWINFO_CIPHER_CCMP) - blobmsg_add_string(buf, NULL, "ccmp"); - - if (nret & IWINFO_CIPHER_WRAP) - blobmsg_add_string(buf, NULL, "wrap"); - - if (nret & IWINFO_CIPHER_AESOCB) - blobmsg_add_string(buf, NULL, "aes-ocb"); - - if (nret & IWINFO_CIPHER_CKIP) - blobmsg_add_string(buf, NULL, "ckip"); - - if (!nret || (nret & IWINFO_CIPHER_NONE)) - blobmsg_add_string(buf, NULL, "none"); - - blobmsg_close_array(buf, a); + iw_add_bit_array(buf, "ciphers", + crypto.pair_ciphers | crypto.group_ciphers, + iw_ciphernames, IWINFO_CIPHER_COUNT, + true, IWINFO_CIPHER_NONE); } blobmsg_close_table(buf, o2); |