From ed484caa030e9276ea8fee02ef4f069df9477aae Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 22 Oct 2024 10:59:55 +0200 Subject: [PATCH] hostapd: add support for querying bss config parameters via ubus Supports reading the same parameters currently being used by iwinfo. Preparation for replacing iwinfo with a rewrite in ucode. Signed-off-by: Felix Fietkau --- .../network/services/hostapd/files/hostapd.uc | 54 +++++++++++++++++++ .../services/hostapd/files/wpa_supplicant.uc | 27 ++++++++++ .../hostapd/src/wpa_supplicant/ucode.c | 27 ++++++++++ 3 files changed, 108 insertions(+) diff --git a/package/network/services/hostapd/files/hostapd.uc b/package/network/services/hostapd/files/hostapd.uc index 6bcb32131d..62fb9cf777 100644 --- a/package/network/services/hostapd/files/hostapd.uc +++ b/package/network/services/hostapd/files/hostapd.uc @@ -30,6 +30,23 @@ hostapd.data.iface_fields = { iapp_interface: true, }; +hostapd.data.bss_info_fields = { + // radio + hw_mode: true, + channel: true, + ieee80211ac: true, + ieee80211ax: true, + + // bss + bssid: true, + ssid: true, + wpa: true, + wpa_key_mgmt: true, + wpa_pairwise: true, + auth_algs: true, + ieee80211w: true, +}; + function iface_remove(cfg) { if (!cfg || !cfg.bss || !cfg.bss[0] || !cfg.bss[0].ifname) @@ -752,6 +769,17 @@ function ex_wrap(func) { }; } +function bss_config(bss_name) { + for (let phy, config in hostapd.data.config) { + if (!config) + continue; + + for (let bss in config.bss) + if (bss.ifname == bss_name) + return [ config, bss ]; + } +} + let main_obj = { reload: { args: { @@ -896,6 +924,32 @@ let main_obj = { return 0; }) }, + bss_info: { + args: { + iface: "" + }, + call: ex_wrap(function(req) { + if (!req.args.iface) + return libubus.STATUS_INVALID_ARGUMENT; + + let config = bss_config(req.args.iface); + if (!config) + return libubus.STATUS_NOT_FOUND; + + let bss = config[1]; + config = config[0]; + let ret = {}; + + for (let line in [ ...config.radio.data, ...bss.data ]) { + let fields = split(line, "=", 2); + let name = fields[0]; + if (hostapd.data.bss_info_fields[name]) + ret[name] = fields[1]; + } + + return ret; + }) + }, }; hostapd.data.ubus = ubus; diff --git a/package/network/services/hostapd/files/wpa_supplicant.uc b/package/network/services/hostapd/files/wpa_supplicant.uc index 31d4534625..eed34f8513 100644 --- a/package/network/services/hostapd/files/wpa_supplicant.uc +++ b/package/network/services/hostapd/files/wpa_supplicant.uc @@ -245,6 +245,33 @@ let main_obj = { return 0; } }, + bss_info: { + args: { + iface: "", + }, + call: function(req) { + let ifname = req.args.iface; + if (!ifname) + return libubus.STATUS_INVALID_ARGUMENT; + + let iface = wpas.interfaces[ifname]; + if (!iface) + return libubus.STATUS_NOT_FOUND; + + let status = iface.ctrl("STATUS"); + if (!status) + return libubus.STATUS_NOT_FOUND; + + let ret = {}; + status = split(status, "\n"); + for (let line in status) { + line = split(line, "=", 2); + ret[line[0]] = line[1]; + } + + return ret; + } + }, }; wpas.data.ubus = ubus; diff --git a/package/network/services/hostapd/src/wpa_supplicant/ucode.c b/package/network/services/hostapd/src/wpa_supplicant/ucode.c index 397f85bde7..9380b301c3 100644 --- a/package/network/services/hostapd/src/wpa_supplicant/ucode.c +++ b/package/network/services/hostapd/src/wpa_supplicant/ucode.c @@ -5,6 +5,7 @@ #include "ap/hostapd.h" #include "wpa_supplicant_i.h" #include "wps_supplicant.h" +#include "ctrl_iface.h" #include "bss.h" #include "ucode.h" @@ -255,6 +256,31 @@ uc_wpas_iface_status(uc_vm_t *vm, size_t nargs) return ret; } +static uc_value_t * +uc_wpas_iface_ctrl(uc_vm_t *vm, size_t nargs) +{ + struct wpa_supplicant *wpa_s = uc_fn_thisval("wpas.iface"); + uc_value_t *arg = uc_fn_arg(0); + size_t reply_len; + uc_value_t *ret; + char *reply; + + if (!wpa_s || ucv_type(arg) != UC_STRING) + return NULL; + + reply = wpa_supplicant_ctrl_iface_process(wpa_s, ucv_string_get(arg), &reply_len); + if (reply_len < 0) + return NULL; + + if (reply_len && reply[reply_len - 1] == '\n') + reply_len--; + + ret = ucv_string_new_length(reply, reply_len); + free(reply); + + return ret; +} + int wpas_ucode_init(struct wpa_global *gl) { static const uc_function_list_t global_fns[] = { @@ -266,6 +292,7 @@ int wpas_ucode_init(struct wpa_global *gl) }; static const uc_function_list_t iface_fns[] = { { "status", uc_wpas_iface_status }, + { "ctrl", uc_wpas_iface_ctrl }, }; uc_value_t *data, *proto; -- 2.30.2