iwinfo: fix handling of accessing nl80211 interfaces via radio*
look up device path via uci instead of assuming a direct phy index Signed-off-by: Felix Fietkau <nbd@openwrt.org> SVN-Revision: 42759
This commit is contained in:
parent
0e439d8a2a
commit
349b20c197
5 changed files with 100 additions and 6 deletions
|
@ -24,7 +24,7 @@ define Package/libiwinfo
|
||||||
SECTION:=libs
|
SECTION:=libs
|
||||||
CATEGORY:=Libraries
|
CATEGORY:=Libraries
|
||||||
TITLE:=Generalized Wireless Information Library (iwinfo)
|
TITLE:=Generalized Wireless Information Library (iwinfo)
|
||||||
DEPENDS:=+PACKAGE_kmod-cfg80211:libnl-tiny
|
DEPENDS:=+PACKAGE_kmod-cfg80211:libnl-tiny +libuci
|
||||||
ABI_VERSION:=$(PKG_RELEASE)
|
ABI_VERSION:=$(PKG_RELEASE)
|
||||||
MAINTAINER:=Jo-Philipp Wich <xm@subsignal.org>
|
MAINTAINER:=Jo-Philipp Wich <xm@subsignal.org>
|
||||||
endef
|
endef
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
IWINFO_BACKENDS = $(BACKENDS)
|
IWINFO_BACKENDS = $(BACKENDS)
|
||||||
IWINFO_CFLAGS = $(CFLAGS) -std=gnu99 -fstrict-aliasing -Iinclude
|
IWINFO_CFLAGS = $(CFLAGS) -std=gnu99 -fstrict-aliasing -Iinclude
|
||||||
|
IWINFO_LDFLAGS = -luci
|
||||||
|
|
||||||
IWINFO_LIB = libiwinfo.so
|
IWINFO_LIB = libiwinfo.so
|
||||||
IWINFO_LIB_LDFLAGS = $(LDFLAGS) -shared
|
IWINFO_LIB_LDFLAGS = $(LDFLAGS) -shared
|
||||||
|
@ -36,9 +37,9 @@ endif
|
||||||
$(CC) $(IWINFO_CFLAGS) $(FPIC) -c -o $@ $<
|
$(CC) $(IWINFO_CFLAGS) $(FPIC) -c -o $@ $<
|
||||||
|
|
||||||
compile: clean $(IWINFO_LIB_OBJ) $(IWINFO_LUA_OBJ) $(IWINFO_CLI_OBJ)
|
compile: clean $(IWINFO_LIB_OBJ) $(IWINFO_LUA_OBJ) $(IWINFO_CLI_OBJ)
|
||||||
$(CC) $(IWINFO_LIB_LDFLAGS) -o $(IWINFO_LIB) $(IWINFO_LIB_OBJ)
|
$(CC) $(IWINFO_LDFLAGS) $(IWINFO_LIB_LDFLAGS) -o $(IWINFO_LIB) $(IWINFO_LIB_OBJ)
|
||||||
$(CC) $(IWINFO_LUA_LDFLAGS) -o $(IWINFO_LUA) $(IWINFO_LUA_OBJ)
|
$(CC) $(IWINFO_LDFLAGS) $(IWINFO_LUA_LDFLAGS) -o $(IWINFO_LUA) $(IWINFO_LUA_OBJ)
|
||||||
$(CC) $(IWINFO_CLI_LDFLAGS) -o $(IWINFO_CLI) $(IWINFO_CLI_OBJ)
|
$(CC) $(IWINFO_LDFLAGS) $(IWINFO_CLI_LDFLAGS) -o $(IWINFO_CLI) $(IWINFO_CLI_OBJ)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o $(IWINFO_LIB) $(IWINFO_LUA) $(IWINFO_CLI)
|
rm -f *.o $(IWINFO_LIB) $(IWINFO_LUA) $(IWINFO_CLI)
|
||||||
|
|
|
@ -21,11 +21,14 @@
|
||||||
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
|
#include <uci.h>
|
||||||
|
|
||||||
#include "iwinfo.h"
|
#include "iwinfo.h"
|
||||||
|
|
||||||
#define LOG10_MAGIC 1.25892541179
|
#define LOG10_MAGIC 1.25892541179
|
||||||
|
|
||||||
|
extern struct uci_context *uci_ctx;
|
||||||
|
|
||||||
int iwinfo_ioctl(int cmd, void *ifr);
|
int iwinfo_ioctl(int cmd, void *ifr);
|
||||||
|
|
||||||
int iwinfo_dbm2mw(int in);
|
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,
|
void iwinfo_parse_rsn(struct iwinfo_crypto_entry *c, uint8_t *data, uint8_t len,
|
||||||
uint8_t defcipher, uint8_t defauth);
|
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
|
#endif
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <glob.h>
|
||||||
#include "iwinfo_nl80211.h"
|
#include "iwinfo_nl80211.h"
|
||||||
|
|
||||||
#define min(x, y) ((x) < (y)) ? (x) : (y)
|
#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);
|
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,
|
static struct nl80211_msg_conveyor * nl80211_msg(const char *ifname,
|
||||||
int cmd, int flags)
|
int cmd, int flags)
|
||||||
{
|
{
|
||||||
|
@ -224,7 +270,7 @@ static struct nl80211_msg_conveyor * nl80211_msg(const char *ifname,
|
||||||
if (!strncmp(ifname, "phy", 3))
|
if (!strncmp(ifname, "phy", 3))
|
||||||
phyidx = atoi(&ifname[3]);
|
phyidx = atoi(&ifname[3]);
|
||||||
else if (!strncmp(ifname, "radio", 5))
|
else if (!strncmp(ifname, "radio", 5))
|
||||||
phyidx = atoi(&ifname[5]);
|
phyidx = nl80211_phy_idx_from_uci(ifname);
|
||||||
else if (!strncmp(ifname, "mon.", 4))
|
else if (!strncmp(ifname, "mon.", 4))
|
||||||
ifidx = if_nametoindex(&ifname[4]);
|
ifidx = if_nametoindex(&ifname[4]);
|
||||||
else
|
else
|
||||||
|
@ -510,7 +556,7 @@ static char * nl80211_phy2ifname(const char *ifname)
|
||||||
else if (!strncmp(ifname, "phy", 3))
|
else if (!strncmp(ifname, "phy", 3))
|
||||||
phyidx = atoi(&ifname[3]);
|
phyidx = atoi(&ifname[3]);
|
||||||
else if (!strncmp(ifname, "radio", 5))
|
else if (!strncmp(ifname, "radio", 5))
|
||||||
phyidx = atoi(&ifname[5]);
|
phyidx = nl80211_phy_idx_from_uci(ifname);
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
|
|
||||||
static int ioctl_socket = -1;
|
static int ioctl_socket = -1;
|
||||||
|
struct uci_context *uci_ctx = NULL;
|
||||||
|
|
||||||
static int iwinfo_ioctl_socket(void)
|
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);
|
data += 2 + (count * 4);
|
||||||
len -= 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;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue