wiphy: Don't store rsne unless needed
Open networks do not contain a RSN element, so storing a 256 byte buffer was too expensive. This patch also has the side-effect of fixing detection of Open Networks. Prior to this, if the scan results did not contain an RSN IE, the 'rsne' variable would be set to all zeros. scan_get_ssid_security would then be called, but instead of a NULL struct ie_rsn_info, a non-null, but zerod out ie_rsn_info would be passed in. This caused the code to work, but for the wrong reasons.
This commit is contained in:
parent
458ad2af77
commit
e69b21ccdf
25
src/wiphy.c
25
src/wiphy.c
|
@ -58,7 +58,7 @@ struct bss {
|
||||||
uint32_t frequency;
|
uint32_t frequency;
|
||||||
int32_t signal_strength;
|
int32_t signal_strength;
|
||||||
uint16_t capability;
|
uint16_t capability;
|
||||||
uint8_t rsne[256];
|
uint8_t *rsne;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct netdev {
|
struct netdev {
|
||||||
|
@ -299,6 +299,7 @@ static void bss_free(void *data)
|
||||||
l_debug("Freeing BSS %02X:%02X:%02X:%02X:%02X:%02X",
|
l_debug("Freeing BSS %02X:%02X:%02X:%02X:%02X:%02X",
|
||||||
bss->addr[0], bss->addr[1], bss->addr[2],
|
bss->addr[0], bss->addr[1], bss->addr[2],
|
||||||
bss->addr[3], bss->addr[4], bss->addr[5]);
|
bss->addr[3], bss->addr[4], bss->addr[5]);
|
||||||
|
l_free(bss->rsne);
|
||||||
l_free(bss);
|
l_free(bss);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -820,7 +821,9 @@ static bool parse_ie(struct bss *bss, const uint8_t **ssid, int *ssid_len,
|
||||||
*ssid = iter.data;
|
*ssid = iter.data;
|
||||||
break;
|
break;
|
||||||
case IE_TYPE_RSN:
|
case IE_TYPE_RSN:
|
||||||
memcpy(bss->rsne, iter.data - 2, iter.len + 2);
|
if (!bss->rsne)
|
||||||
|
bss->rsne = l_memdup(iter.data - 2,
|
||||||
|
iter.len + 2);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -849,10 +852,8 @@ static void parse_bss(struct netdev *netdev, struct l_genl_attr *attr)
|
||||||
const uint8_t *ssid = NULL;
|
const uint8_t *ssid = NULL;
|
||||||
int ssid_len;
|
int ssid_len;
|
||||||
struct network *network = NULL;
|
struct network *network = NULL;
|
||||||
struct ie_rsn_info rsne;
|
|
||||||
enum scan_ssid_security ssid_security;
|
enum scan_ssid_security ssid_security;
|
||||||
const char *id;
|
const char *id;
|
||||||
int res;
|
|
||||||
|
|
||||||
bss = l_new(struct bss, 1);
|
bss = l_new(struct bss, 1);
|
||||||
|
|
||||||
|
@ -906,16 +907,28 @@ static void parse_bss(struct netdev *netdev, struct l_genl_attr *attr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* TODO: Check whether WPA element is present
|
||||||
|
*
|
||||||
|
* If we have the RSN element, try to parse it and figure out the
|
||||||
|
* security parameters.
|
||||||
|
*
|
||||||
* Length was already validated by parse_ie, so use the one from the
|
* Length was already validated by parse_ie, so use the one from the
|
||||||
* IE directly.
|
* IE directly.
|
||||||
*/
|
*/
|
||||||
res = ie_parse_rsne_from_data(bss->rsne, bss->rsne[1] + 2, &rsne);
|
if (bss->rsne) {
|
||||||
|
struct ie_rsn_info rsne;
|
||||||
|
int res = ie_parse_rsne_from_data(bss->rsne, bss->rsne[1] + 2,
|
||||||
|
&rsne);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
l_debug("Cannot parse RSN field (%d, %s)", res, strerror(-res));
|
l_debug("Cannot parse RSN field (%d, %s)",
|
||||||
|
res, strerror(-res));
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssid_security = scan_get_ssid_security(bss->capability, &rsne);
|
ssid_security = scan_get_ssid_security(bss->capability, &rsne);
|
||||||
|
} else
|
||||||
|
ssid_security = scan_get_ssid_security(bss->capability, NULL);
|
||||||
|
|
||||||
id = iwd_network_get_id(ssid, ssid_len, ssid_security);
|
id = iwd_network_get_id(ssid, ssid_len, ssid_security);
|
||||||
|
|
||||||
network = l_hashmap_lookup(netdev->networks, id);
|
network = l_hashmap_lookup(netdev->networks, id);
|
||||||
|
|
Loading…
Reference in New Issue