summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJo-Philipp Wich <jow@openwrt.org>2009-09-23 18:04:29 +0000
committerJo-Philipp Wich <jow@openwrt.org>2009-09-23 18:04:29 +0000
commit48465cebabb7ebf34f1471eecfff9f9011b5b442 (patch)
treecbcf6090c50f416261f984d0981449bf076d4d5c
parent79022dcc636bebe01f6042f68fd8b09a58b6802c (diff)
libs/iwinfo: find/autocreate madwifi vap if scan on wifi0 is requested
-rw-r--r--libs/iwinfo/src/iwinfo_madwifi.c104
1 files changed, 95 insertions, 9 deletions
diff --git a/libs/iwinfo/src/iwinfo_madwifi.c b/libs/iwinfo/src/iwinfo_madwifi.c
index e2bde1c14e..1fe777f1d5 100644
--- a/libs/iwinfo/src/iwinfo_madwifi.c
+++ b/libs/iwinfo/src/iwinfo_madwifi.c
@@ -59,27 +59,62 @@ static int get80211priv(const char *ifname, int op, void *data, size_t len)
return iwr.u.data.length;
}
-
-int madwifi_probe(const char *ifname)
+static int madwifi_isvap(const char *ifname, const char *wifiname)
{
int fd, ret;
char path[32];
- char name[5];
+ char name[IFNAMSIZ];
+
+ ret = 0;
+
+ if( strlen(ifname) <= 9 )
+ {
+ sprintf(path, "/proc/sys/net/%s/%%parent", ifname);
+
+ if( (fd = open(path, O_RDONLY)) > -1 )
+ {
+ if( wifiname != NULL )
+ {
+ if( read(fd, name, strlen(wifiname)) == strlen(wifiname) )
+ ret = strncmp(name, wifiname, strlen(wifiname)) ? 0 : 1;
+ }
+ else if( read(fd, name, 4) == 4 )
+ {
+ ret = strncmp(name, "wifi", 4) ? 0 : 1;
+ }
+
+ (void) close(fd);
+ }
+ }
+
+ return ret;
+}
+
+static int madwifi_iswifi(const char *ifname)
+{
+ int ret;
+ char path[32];
+ struct stat s;
- sprintf(path, "/proc/sys/net/%s/%%parent", ifname);
ret = 0;
- if( (fd = open(path, O_RDONLY)) > -1 )
+ if( strlen(ifname) <= 7 )
{
- if( read(fd, name, 4) == 4 )
- ret = strncmp(name, "wifi", 4) ? 0 : 1;
+ sprintf(path, "/proc/sys/dev/%s/diversity", ifname);
- (void) close(fd);
+ if( ! stat(path, &s) )
+ ret = (s.st_mode & S_IFREG);
}
return ret;
}
+
+int madwifi_probe(const char *ifname)
+{
+ return ( madwifi_isvap(ifname, NULL) || madwifi_iswifi(ifname) );
+}
+
int madwifi_get_mode(const char *ifname, char *buf)
{
return wext_get_mode(ifname, buf);
@@ -405,7 +440,58 @@ int madwifi_get_txpwrlist(const char *ifname, char *buf, int *len)
int madwifi_get_scanlist(const char *ifname, char *buf, int *len)
{
- return wext_get_scanlist(ifname, buf, len);
+ int ret;
+ char cmd[256];
+ DIR *proc;
+ struct dirent *e;
+
+ ret = -1;
+
+ /* We got a wifiX device passed, try to lookup a vap on it */
+ if( madwifi_iswifi(ifname) )
+ {
+ if( (proc = opendir("/proc/sys/net/")) != NULL )
+ {
+ while( (e = readdir(proc)) != NULL )
+ {
+ if( madwifi_isvap(e->d_name, ifname) )
+ {
+ sprintf(cmd, "ifconfig %s up", e->d_name);
+
+ if( ! WEXITSTATUS(system(cmd)) )
+ {
+ ret = wext_get_scanlist(e->d_name, buf, len);
+ break;
+ }
+ }
+ }
+
+ closedir(proc);
+ }
+
+ /* Still nothing found, try to create a vap */
+ if( ret == -1 )
+ {
+ sprintf(cmd, "wlanconfig ath-scan create nounit "
+ "wlandev %s wlanmode sta >/dev/null", ifname);
+
+ if( ! WEXITSTATUS(system(cmd)) && ! WEXITSTATUS(system("ifconfig ath-scan up")) )
+ {
+ ret = wext_get_scanlist("ath-scan", buf, len);
+
+ (void) WEXITSTATUS(system("ifconfig ath-scan down"));
+ (void) WEXITSTATUS(system("wlanconfig ath-scan destroy"));
+ }
+ }
+ }
+
+ /* Got athX device? */
+ else if( madwifi_isvap(ifname, NULL) )
+ {
+ ret = wext_get_scanlist(ifname, buf, len);
+ }
+
+ return ret;
}
int madwifi_get_mbssid_support(const char *ifname, int *buf)