aboutsummaryrefslogtreecommitdiffstats
path: root/package/network/utils/iwinfo/src
diff options
context:
space:
mode:
Diffstat (limited to 'package/network/utils/iwinfo/src')
-rw-r--r--package/network/utils/iwinfo/src/Makefile7
-rw-r--r--package/network/utils/iwinfo/src/include/iwinfo/utils.h6
-rw-r--r--package/network/utils/iwinfo/src/iwinfo_nl80211.c50
-rw-r--r--package/network/utils/iwinfo/src/iwinfo_utils.c41
4 files changed, 99 insertions, 5 deletions
diff --git a/package/network/utils/iwinfo/src/Makefile b/package/network/utils/iwinfo/src/Makefile
index 572bef9f97..60341f7c2b 100644
--- a/package/network/utils/iwinfo/src/Makefile
+++ b/package/network/utils/iwinfo/src/Makefile
@@ -1,5 +1,6 @@
IWINFO_BACKENDS = $(BACKENDS)
IWINFO_CFLAGS = $(CFLAGS) -std=gnu99 -fstrict-aliasing -Iinclude
+IWINFO_LDFLAGS = -luci
IWINFO_LIB = libiwinfo.so
IWINFO_LIB_LDFLAGS = $(LDFLAGS) -shared
@@ -36,9 +37,9 @@ endif
$(CC) $(IWINFO_CFLAGS) $(FPIC) -c -o $@ $<
compile: clean $(IWINFO_LIB_OBJ) $(IWINFO_LUA_OBJ) $(IWINFO_CLI_OBJ)
- $(CC) $(IWINFO_LIB_LDFLAGS) -o $(IWINFO_LIB) $(IWINFO_LIB_OBJ)
- $(CC) $(IWINFO_LUA_LDFLAGS) -o $(IWINFO_LUA) $(IWINFO_LUA_OBJ)
- $(CC) $(IWINFO_CLI_LDFLAGS) -o $(IWINFO_CLI) $(IWINFO_CLI_OBJ)
+ $(CC) $(IWINFO_LDFLAGS) $(IWINFO_LIB_LDFLAGS) -o $(IWINFO_LIB) $(IWINFO_LIB_OBJ)
+ $(CC) $(IWINFO_LDFLAGS) $(IWINFO_LUA_LDFLAGS) -o $(IWINFO_LUA) $(IWINFO_LUA_OBJ)
+ $(CC) $(IWINFO_LDFLAGS) $(IWINFO_CLI_LDFLAGS) -o $(IWINFO_CLI) $(IWINFO_CLI_OBJ)
clean:
rm -f *.o $(IWINFO_LIB) $(IWINFO_LUA) $(IWINFO_CLI)
diff --git a/package/network/utils/iwinfo/src/include/iwinfo/utils.h b/package/network/utils/iwinfo/src/include/iwinfo/utils.h
index d58ec5fb75..d4f32e4d1e 100644
--- a/package/network/utils/iwinfo/src/include/iwinfo/utils.h
+++ b/package/network/utils/iwinfo/src/include/iwinfo/utils.h
@@ -21,11 +21,14 @@
#include <sys/socket.h>
#include <net/if.h>
+#include <uci.h>
#include "iwinfo.h"
#define LOG10_MAGIC 1.25892541179
+extern struct uci_context *uci_ctx;
+
int iwinfo_ioctl(int cmd, void *ifr);
int iwinfo_dbm2mw(int in);
@@ -44,4 +47,7 @@ int iwinfo_hardware_id_from_mtd(struct iwinfo_hardware_id *id);
void iwinfo_parse_rsn(struct iwinfo_crypto_entry *c, uint8_t *data, uint8_t len,
uint8_t defcipher, uint8_t defauth);
+struct uci_section *iwinfo_uci_get_radio(const char *name, const char *type);
+void iwinfo_uci_free(void);
+
#endif
diff --git a/package/network/utils/iwinfo/src/iwinfo_nl80211.c b/package/network/utils/iwinfo/src/iwinfo_nl80211.c
index 7711b61102..66ace26101 100644
--- a/package/network/utils/iwinfo/src/iwinfo_nl80211.c
+++ b/package/network/utils/iwinfo/src/iwinfo_nl80211.c
@@ -23,6 +23,7 @@
*/
#include <limits.h>
+#include <glob.h>
#include "iwinfo_nl80211.h"
#define min(x, y) ((x) < (y)) ? (x) : (y)
@@ -209,6 +210,51 @@ static struct nl80211_msg_conveyor * nl80211_ctl(int cmd, int flags)
return nl80211_new(nls->nlctrl, cmd, flags);
}
+static int nl80211_phy_idx_from_uci(const char *name)
+{
+ struct uci_section *s;
+ const char *opt;
+ char buf[128];
+ glob_t gl;
+ FILE *f = NULL;
+ int idx = -1;
+ int err;
+
+ s = iwinfo_uci_get_radio(name, "mac80211");
+ if (!s)
+ goto free;
+
+ opt = uci_lookup_option_string(uci_ctx, s, "path");
+ if (!opt)
+ goto free;
+
+ snprintf(buf, sizeof(buf), "/sys/devices/%s/ieee80211/*/index", opt);
+ err = glob(buf, 0, NULL, &gl);
+ if (err)
+ goto free;
+
+ if (gl.gl_pathc)
+ f = fopen(gl.gl_pathv[0], "r");
+
+ globfree(&gl);
+
+ if (!f)
+ goto free;
+
+ err = fread(buf, 1, sizeof(buf) - 1, f);
+ fclose(f);
+
+ if (err <= 0)
+ goto free;
+
+ buf[err] = 0;
+ idx = atoi(buf);
+
+free:
+ iwinfo_uci_free();
+ return idx;
+}
+
static struct nl80211_msg_conveyor * nl80211_msg(const char *ifname,
int cmd, int flags)
{
@@ -224,7 +270,7 @@ static struct nl80211_msg_conveyor * nl80211_msg(const char *ifname,
if (!strncmp(ifname, "phy", 3))
phyidx = atoi(&ifname[3]);
else if (!strncmp(ifname, "radio", 5))
- phyidx = atoi(&ifname[5]);
+ phyidx = nl80211_phy_idx_from_uci(ifname);
else if (!strncmp(ifname, "mon.", 4))
ifidx = if_nametoindex(&ifname[4]);
else
@@ -510,7 +556,7 @@ static char * nl80211_phy2ifname(const char *ifname)
else if (!strncmp(ifname, "phy", 3))
phyidx = atoi(&ifname[3]);
else if (!strncmp(ifname, "radio", 5))
- phyidx = atoi(&ifname[5]);
+ phyidx = nl80211_phy_idx_from_uci(ifname);
else
return NULL;
diff --git a/package/network/utils/iwinfo/src/iwinfo_utils.c b/package/network/utils/iwinfo/src/iwinfo_utils.c
index 4a824337a9..b313ea2049 100644
--- a/package/network/utils/iwinfo/src/iwinfo_utils.c
+++ b/package/network/utils/iwinfo/src/iwinfo_utils.c
@@ -24,6 +24,7 @@
static int ioctl_socket = -1;
+struct uci_context *uci_ctx = NULL;
static int iwinfo_ioctl_socket(void)
{
@@ -365,3 +366,43 @@ void iwinfo_parse_rsn(struct iwinfo_crypto_entry *c, uint8_t *data, uint8_t len,
data += 2 + (count * 4);
len -= 2 + (count * 4);
}
+
+struct uci_section *iwinfo_uci_get_radio(const char *name, const char *type)
+{
+ struct uci_ptr ptr = {
+ .package = "wireless",
+ .section = name,
+ };
+ const char *opt;
+
+ if (!uci_ctx) {
+ uci_ctx = uci_alloc_context();
+ if (!uci_ctx)
+ return NULL;
+ }
+
+ memset(&ptr, 0, sizeof(ptr));
+ ptr.package = "wireless";
+ ptr.section = name;
+
+ if (uci_lookup_ptr(uci_ctx, &ptr, NULL, false))
+ return NULL;
+
+ if (!ptr.s || strcmp(ptr.s->type, "wifi-device") != 0)
+ return NULL;
+
+ opt = uci_lookup_option_string(uci_ctx, ptr.s, "type");
+ if (!opt || strcmp(opt, type) != 0)
+ return NULL;
+
+ return ptr.s;
+}
+
+void iwinfo_uci_free(void)
+{
+ if (!uci_ctx)
+ return;
+
+ uci_free_context(uci_ctx);
+ uci_ctx = NULL;
+}