summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2019-10-15 14:21:38 +0200
committerJo-Philipp Wich <jo@mein.io>2019-10-15 14:50:56 +0200
commita29b7d4e26a8d97e48c2a899dda3665d385b95db (patch)
treee5d7203ccaf922ee59f53fc4e9dd0208f985f3ec
parent2a95086db2b730346d87c320e2c753126c4ff795 (diff)
downloadiwinfo-a29b7d4e26a8d97e48c2a899dda3665d385b95db.tar.gz
nl80211: align path to phy mapping logic with mac80211.sh
The mac80211.sh implementation of the uci "path" option compares the readlink() results of each /sys/class/ieee80211/*/device link to find the proper phy directory while iwinfo so far tried to construct a full path out of the uci value. The iwinfo approach appears to fail under certain circumstances, e.g. with Hyper-V systems utilizing PCI passthrough for the radio devices. This commit mimicks the behaviour of mac80211.sh more closely to achieve the same results. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r--iwinfo_nl80211.c50
1 files changed, 37 insertions, 13 deletions
diff --git a/iwinfo_nl80211.c b/iwinfo_nl80211.c
index 4d20489..c7b0222 100644
--- a/iwinfo_nl80211.c
+++ b/iwinfo_nl80211.c
@@ -26,6 +26,7 @@
#include <glob.h>
#include <fnmatch.h>
#include <stdarg.h>
+#include <stdlib.h>
#include "iwinfo_nl80211.h"
@@ -234,26 +235,49 @@ static struct nl80211_msg_conveyor * nl80211_ctl(int cmd, int flags)
static int nl80211_phy_idx_from_uci_path(struct uci_section *s)
{
- const char *opt;
- char buf[128];
+ size_t linklen, pathlen;
+ char buf[128], *link;
+ struct dirent *e;
+ const char *path;
int idx = -1;
- glob_t gl;
+ DIR *d;
- opt = uci_lookup_option_string(uci_ctx, s, "path");
- if (!opt)
+ path = uci_lookup_option_string(uci_ctx, s, "path");
+ if (!path)
return -1;
- snprintf(buf, sizeof(buf), "/sys/devices/%s/ieee80211/*/index", opt); /**/
- if (glob(buf, 0, NULL, &gl))
- snprintf(buf, sizeof(buf), "/sys/devices/platform/%s/ieee80211/*/index", opt); /**/
+ if ((d = opendir("/sys/class/ieee80211")) != NULL)
+ {
+ while ((e = readdir(d)) != NULL)
+ {
+ snprintf(buf, sizeof(buf), "/sys/class/ieee80211/%s/device", e->d_name);
- if (glob(buf, 0, NULL, &gl))
- return -1;
+ link = realpath(buf, NULL);
- if (gl.gl_pathc > 0)
- idx = nl80211_readint(gl.gl_pathv[0]);
+ if (link == NULL)
+ continue;
- globfree(&gl);
+ linklen = strlen(link);
+ pathlen = strlen(path);
+
+ if (pathlen >= linklen || strcmp(link + (linklen - pathlen), path))
+ linklen = 0;
+
+ free(link);
+
+ if (linklen == 0)
+ continue;
+
+ snprintf(buf, sizeof(buf), "/sys/class/ieee80211/%s/index", e->d_name);
+
+ idx = nl80211_readint(buf);
+
+ if (idx >= 0)
+ break;
+ }
+
+ closedir(d);
+ }
return idx;
}