libiwinfo: fix scan issues in nl80211, encryption detection fixes for madwifi
This commit is contained in:
parent
2530590e50
commit
8c9acb01f4
3 changed files with 69 additions and 37 deletions
|
@ -7,7 +7,7 @@
|
||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=libiwinfo
|
PKG_NAME:=libiwinfo
|
||||||
PKG_RELEASE:=12
|
PKG_RELEASE:=13
|
||||||
|
|
||||||
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
|
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
|
||||||
|
|
||||||
|
|
|
@ -549,13 +549,23 @@ int madwifi_get_quality_max(const char *ifname, int *buf)
|
||||||
int madwifi_get_encryption(const char *ifname, char *buf)
|
int madwifi_get_encryption(const char *ifname, char *buf)
|
||||||
{
|
{
|
||||||
int ciphers = 0, key_len = 0;
|
int ciphers = 0, key_len = 0;
|
||||||
|
char keybuf[IW_ENCODING_TOKEN_MAX];
|
||||||
struct iwinfo_crypto_entry *c = (struct iwinfo_crypto_entry *)buf;
|
struct iwinfo_crypto_entry *c = (struct iwinfo_crypto_entry *)buf;
|
||||||
struct iwreq wrq;
|
struct iwreq wrq;
|
||||||
struct ieee80211req_key wk;
|
struct ieee80211req_key wk;
|
||||||
|
|
||||||
memset(&wrq, 0, sizeof(wrq));
|
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 */
|
/* Get wpa protocol version */
|
||||||
wrq.u.mode = IEEE80211_PARAM_WPA;
|
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 */
|
/* Get key information */
|
||||||
if( get80211priv(ifname, IEEE80211_IOCTL_GETKEY, &wk, sizeof(wk)) >= 0 )
|
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);
|
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 */
|
/* Get used pairwise ciphers */
|
||||||
wrq.u.mode = IEEE80211_PARAM_UCASTCIPHERS;
|
wrq.u.mode = IEEE80211_PARAM_UCASTCIPHERS;
|
||||||
if( madwifi_wrq(&wrq, ifname, IEEE80211_IOCTL_GETPARAM, NULL, 0) >= 0 )
|
if( madwifi_wrq(&wrq, ifname, IEEE80211_IOCTL_GETPARAM, NULL, 0) >= 0 )
|
||||||
{
|
{
|
||||||
ciphers = wrq.u.mode;
|
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;
|
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;
|
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;
|
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;
|
c->pair_ciphers |= IWINFO_CIPHER_CKIP;
|
||||||
|
|
||||||
if( ciphers & (1 << IEEE80211_CIPHER_WEP) )
|
if( ciphers & (1 << IEEE80211_CIPHER_WEP) )
|
||||||
|
@ -632,6 +640,8 @@ int madwifi_get_encryption(const char *ifname, char *buf)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
c->pair_ciphers = IWINFO_CIPHER_WEP40 |
|
||||||
|
IWINFO_CIPHER_WEP104;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -644,9 +654,9 @@ int madwifi_get_encryption(const char *ifname, char *buf)
|
||||||
wrq.u.mode = IEEE80211_PARAM_MCASTCIPHER;
|
wrq.u.mode = IEEE80211_PARAM_MCASTCIPHER;
|
||||||
if( madwifi_wrq(&wrq, ifname, IEEE80211_IOCTL_GETPARAM, NULL, 0) >= 0 )
|
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:
|
case IEEE80211_CIPHER_TKIP:
|
||||||
c->group_ciphers |= IWINFO_CIPHER_TKIP;
|
c->group_ciphers |= IWINFO_CIPHER_TKIP;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -333,18 +333,37 @@ static char * nl80211_hostapd_info(const char *ifname)
|
||||||
return NULL;
|
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;
|
char *rv = NULL;
|
||||||
size_t remote_length, local_length;
|
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 local = { 0 };
|
||||||
struct sockaddr_un remote = { 0 };
|
struct sockaddr_un remote = { 0 };
|
||||||
|
|
||||||
fd_set rfds;
|
|
||||||
|
|
||||||
sock = socket(PF_UNIX, SOCK_DGRAM, 0);
|
sock = socket(PF_UNIX, SOCK_DGRAM, 0);
|
||||||
if( sock < 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) )
|
if( bind(sock, (struct sockaddr *) &local, local_length) )
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
|
||||||
|
send(sock, "ATTACH", 6, 0);
|
||||||
|
|
||||||
|
if( nl80211_wpactl_recv(sock, buffer, sizeof(buffer)) <= 0 )
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
|
||||||
send(sock, cmd, strlen(cmd), 0);
|
send(sock, cmd, strlen(cmd), 0);
|
||||||
|
|
||||||
while( 1 )
|
while( 1 )
|
||||||
{
|
{
|
||||||
FD_ZERO(&rfds);
|
if( nl80211_wpactl_recv(sock, buffer, sizeof(buffer)) <= 0 )
|
||||||
FD_SET(sock, &rfds);
|
{
|
||||||
|
if( event )
|
||||||
|
continue;
|
||||||
|
|
||||||
if( select(sock + 1, &rfds, NULL, NULL, &tv) < 0 )
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if( !FD_ISSET(sock, &rfds) )
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if( (len = recv(sock, buffer, sizeof(buffer), 0)) <= 0 )
|
if( (!event && buffer[0] != '<') || strstr(buffer, event) )
|
||||||
goto out;
|
|
||||||
|
|
||||||
buffer[len] = 0;
|
|
||||||
|
|
||||||
if( buffer[0] != '<' )
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -933,7 +953,7 @@ int nl80211_get_encryption(const char *ifname, char *buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* WPA supplicant */
|
/* 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")) )
|
(val = nl80211_getval(NULL, res, "pairwise_cipher")) )
|
||||||
{
|
{
|
||||||
/* WEP */
|
/* 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;
|
struct iwinfo_scanlist_entry *e = (struct iwinfo_scanlist_entry *)buf;
|
||||||
|
|
||||||
/* WPA supplicant */
|
/* 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_wpactl_info(ifname, "SCAN_RESULTS", NULL)) )
|
||||||
|
|
||||||
if( (res = nl80211_wpasupp_info(ifname, "SCAN_RESULTS")) )
|
|
||||||
{
|
{
|
||||||
nl80211_get_quality_max(ifname, &qmax);
|
nl80211_get_quality_max(ifname, &qmax);
|
||||||
|
|
||||||
|
@ -1262,7 +1280,7 @@ int nl80211_get_scanlist(const char *ifname, char *buf, int *len)
|
||||||
|
|
||||||
count = 0;
|
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, &freq, &rssi, cipher, ssid) > 0 )
|
||||||
{
|
{
|
||||||
/* BSSID */
|
/* BSSID */
|
||||||
|
@ -1315,6 +1333,10 @@ int nl80211_get_scanlist(const char *ifname, char *buf, int *len)
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
e++;
|
e++;
|
||||||
|
|
||||||
|
memset(ssid, 0, sizeof(ssid));
|
||||||
|
memset(bssid, 0, sizeof(bssid));
|
||||||
|
memset(cipher, 0, sizeof(cipher));
|
||||||
}
|
}
|
||||||
|
|
||||||
*len = count * sizeof(struct iwinfo_scanlist_entry);
|
*len = count * sizeof(struct iwinfo_scanlist_entry);
|
||||||
|
|
Loading…
Reference in a new issue