summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJo-Philipp Wich <jow@openwrt.org>2010-12-04 23:25:14 +0000
committerJo-Philipp Wich <jow@openwrt.org>2010-12-04 23:25:14 +0000
commit8c9acb01f4e345a096042a994e1655b21689a3cf (patch)
tree46829481b6b124430b37f6361f5699bf242dfe09
parent2530590e50ec8c0fddc9f9ce03c0b65b5476a8bd (diff)
libiwinfo: fix scan issues in nl80211, encryption detection fixes for madwifi
-rw-r--r--contrib/package/iwinfo/Makefile2
-rw-r--r--contrib/package/iwinfo/src/iwinfo_madwifi.c36
-rw-r--r--contrib/package/iwinfo/src/iwinfo_nl80211.c68
3 files changed, 69 insertions, 37 deletions
diff --git a/contrib/package/iwinfo/Makefile b/contrib/package/iwinfo/Makefile
index e9edc2ccc..c89091003 100644
--- a/contrib/package/iwinfo/Makefile
+++ b/contrib/package/iwinfo/Makefile
@@ -7,7 +7,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=libiwinfo
-PKG_RELEASE:=12
+PKG_RELEASE:=13
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
diff --git a/contrib/package/iwinfo/src/iwinfo_madwifi.c b/contrib/package/iwinfo/src/iwinfo_madwifi.c
index a6070132b..59c42dbc9 100644
--- a/contrib/package/iwinfo/src/iwinfo_madwifi.c
+++ b/contrib/package/iwinfo/src/iwinfo_madwifi.c
@@ -549,13 +549,23 @@ int madwifi_get_quality_max(const char *ifname, int *buf)
int madwifi_get_encryption(const char *ifname, char *buf)
{
int ciphers = 0, key_len = 0;
+ char keybuf[IW_ENCODING_TOKEN_MAX];
struct iwinfo_crypto_entry *c = (struct iwinfo_crypto_entry *)buf;
struct iwreq wrq;
struct ieee80211req_key wk;
memset(&wrq, 0, sizeof(wrq));
- memset(&wk, 0, sizeof(wk));
- memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
+
+ /* Obtain key info */
+ if( madwifi_wrq(&wrq, ifname, SIOCGIWENCODE, keybuf, sizeof(keybuf)) < 0 )
+ return -1;
+
+ /* Have any encryption? */
+ if( (wrq.u.data.flags & IW_ENCODE_DISABLED) || (wrq.u.data.length == 0) )
+ return 0;
+
+ /* Save key len */
+ key_len = wrq.u.data.length;
/* Get wpa protocol version */
wrq.u.mode = IEEE80211_PARAM_WPA;
@@ -589,6 +599,9 @@ int madwifi_get_encryption(const char *ifname, char *buf)
}
}
+ memset(&wk, 0, sizeof(wk));
+ memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
+
/* Get key information */
if( get80211priv(ifname, IEEE80211_IOCTL_GETKEY, &wk, sizeof(wk)) >= 0 )
{
@@ -597,27 +610,22 @@ int madwifi_get_encryption(const char *ifname, char *buf)
c->auth_algs = (IWINFO_AUTH_OPEN | IWINFO_AUTH_SHARED);
}
- /* Get group key length */
- wrq.u.mode = IEEE80211_PARAM_MCASTKEYLEN;
- if( madwifi_wrq(&wrq, ifname, IEEE80211_IOCTL_GETPARAM, NULL, 0) >= 0 )
- key_len = wrq.u.mode;
-
/* Get used pairwise ciphers */
wrq.u.mode = IEEE80211_PARAM_UCASTCIPHERS;
if( madwifi_wrq(&wrq, ifname, IEEE80211_IOCTL_GETPARAM, NULL, 0) >= 0 )
{
ciphers = wrq.u.mode;
- if( ciphers & (1 << IEEE80211_CIPHER_TKIP) )
+ if( c->wpa_version && ciphers & (1 << IEEE80211_CIPHER_TKIP) )
c->pair_ciphers |= IWINFO_CIPHER_TKIP;
- if( ciphers & (1 << IEEE80211_CIPHER_AES_CCM) )
+ if( c->wpa_version && ciphers & (1 << IEEE80211_CIPHER_AES_CCM) )
c->pair_ciphers |= IWINFO_CIPHER_CCMP;
- if( ciphers & (1 << IEEE80211_CIPHER_AES_OCB) )
+ if( c->wpa_version && ciphers & (1 << IEEE80211_CIPHER_AES_OCB) )
c->pair_ciphers |= IWINFO_CIPHER_AESOCB;
- if( ciphers & (1 << IEEE80211_CIPHER_CKIP) )
+ if( c->wpa_version && ciphers & (1 << IEEE80211_CIPHER_CKIP) )
c->pair_ciphers |= IWINFO_CIPHER_CKIP;
if( ciphers & (1 << IEEE80211_CIPHER_WEP) )
@@ -632,6 +640,8 @@ int madwifi_get_encryption(const char *ifname, char *buf)
break;
default:
+ c->pair_ciphers = IWINFO_CIPHER_WEP40 |
+ IWINFO_CIPHER_WEP104;
break;
}
}
@@ -644,9 +654,9 @@ int madwifi_get_encryption(const char *ifname, char *buf)
wrq.u.mode = IEEE80211_PARAM_MCASTCIPHER;
if( madwifi_wrq(&wrq, ifname, IEEE80211_IOCTL_GETPARAM, NULL, 0) >= 0 )
{
- ciphers = wrq.u.mode;
+ ciphers = c->wpa_version ? wrq.u.mode : IEEE80211_CIPHER_WEP;
- switch(wrq.u.mode) {
+ switch(ciphers) {
case IEEE80211_CIPHER_TKIP:
c->group_ciphers |= IWINFO_CIPHER_TKIP;
break;
diff --git a/contrib/package/iwinfo/src/iwinfo_nl80211.c b/contrib/package/iwinfo/src/iwinfo_nl80211.c
index 4868db10e..aca2be233 100644
--- a/contrib/package/iwinfo/src/iwinfo_nl80211.c
+++ b/contrib/package/iwinfo/src/iwinfo_nl80211.c
@@ -333,18 +333,37 @@ static char * nl80211_hostapd_info(const char *ifname)
return NULL;
}
-static char * nl80211_wpasupp_info(const char *ifname, const char *cmd)
+static inline int nl80211_wpactl_recv(int sock, char *buf, int blen)
{
- int sock = -1, len;
+ fd_set rfds;
+ struct timeval tv = { 2, 0 };
+
+ FD_ZERO(&rfds);
+ FD_SET(sock, &rfds);
+
+ memset(buf, 0, blen);
+
+
+ if( select(sock + 1, &rfds, NULL, NULL, &tv) < 0 )
+ return -1;
+
+ if( !FD_ISSET(sock, &rfds) )
+ return -1;
+
+ return recv(sock, buf, blen, 0);
+}
+
+static char * nl80211_wpactl_info(const char *ifname, const char *cmd,
+ const char *event)
+{
+ int sock = -1;
char *rv = NULL;
size_t remote_length, local_length;
- static char buffer[1024] = { 0 };
+ static char buffer[10240] = { 0 };
- struct timeval tv = { 2, 0 };
struct sockaddr_un local = { 0 };
struct sockaddr_un remote = { 0 };
- fd_set rfds;
sock = socket(PF_UNIX, SOCK_DGRAM, 0);
if( sock < 0 )
@@ -367,25 +386,26 @@ static char * nl80211_wpasupp_info(const char *ifname, const char *cmd)
if( bind(sock, (struct sockaddr *) &local, local_length) )
goto out;
+
+ send(sock, "ATTACH", 6, 0);
+
+ if( nl80211_wpactl_recv(sock, buffer, sizeof(buffer)) <= 0 )
+ goto out;
+
+
send(sock, cmd, strlen(cmd), 0);
while( 1 )
{
- FD_ZERO(&rfds);
- FD_SET(sock, &rfds);
-
- if( select(sock + 1, &rfds, NULL, NULL, &tv) < 0 )
- goto out;
+ if( nl80211_wpactl_recv(sock, buffer, sizeof(buffer)) <= 0 )
+ {
+ if( event )
+ continue;
- if( !FD_ISSET(sock, &rfds) )
break;
+ }
- if( (len = recv(sock, buffer, sizeof(buffer), 0)) <= 0 )
- goto out;
-
- buffer[len] = 0;
-
- if( buffer[0] != '<' )
+ if( (!event && buffer[0] != '<') || strstr(buffer, event) )
break;
}
@@ -933,7 +953,7 @@ int nl80211_get_encryption(const char *ifname, char *buf)
}
/* WPA supplicant */
- else if( (res = nl80211_wpasupp_info(ifname, "STATUS")) &&
+ else if( (res = nl80211_wpactl_info(ifname, "STATUS", NULL)) &&
(val = nl80211_getval(NULL, res, "pairwise_cipher")) )
{
/* WEP */
@@ -1249,11 +1269,9 @@ int nl80211_get_scanlist(const char *ifname, char *buf, int *len)
struct iwinfo_scanlist_entry *e = (struct iwinfo_scanlist_entry *)buf;
/* WPA supplicant */
- if( (res = nl80211_wpasupp_info(ifname, "SCAN")) && !strcmp(res, "OK\n") )
+ if( (res = nl80211_wpactl_info(ifname, "SCAN", "CTRL-EVENT-SCAN-RESULTS")) )
{
- sleep(2);
-
- if( (res = nl80211_wpasupp_info(ifname, "SCAN_RESULTS")) )
+ if( (res = nl80211_wpactl_info(ifname, "SCAN_RESULTS", NULL)) )
{
nl80211_get_quality_max(ifname, &qmax);
@@ -1262,7 +1280,7 @@ int nl80211_get_scanlist(const char *ifname, char *buf, int *len)
count = 0;
- while( sscanf(res, "%17s %d %d %255s %127[^\n]\n",
+ while( sscanf(res, "%17s %d %d %255s%*[ \t]%127[^\n]\n",
bssid, &freq, &rssi, cipher, ssid) > 0 )
{
/* BSSID */
@@ -1315,6 +1333,10 @@ int nl80211_get_scanlist(const char *ifname, char *buf, int *len)
count++;
e++;
+
+ memset(ssid, 0, sizeof(ssid));
+ memset(bssid, 0, sizeof(bssid));
+ memset(cipher, 0, sizeof(cipher));
}
*len = count * sizeof(struct iwinfo_scanlist_entry);