scan: use structure for OWE transition parsing

This changes scan_bss from using separate members for each
OWE transition element data type (ssid, ssid_len, and bssid)
to a structure that holds them all.

This is being done because OWE transition has option operating
class and channel bytes which will soon be parsed. This would
end up needing 5 separate members in scan_bss which is a bit
much for a single IE that needs to be parsed.

This makes checking the presense of the IE more convenient
as well since it can be done with a simple NULL pointer check
rather than having to l_memeqzero the BSSID.
This commit is contained in:
James Prestwood 2021-09-22 11:26:51 -07:00 committed by Denis Kenzior
parent 421f068903
commit 22ff2a5f79
6 changed files with 47 additions and 50 deletions

View File

@ -2501,9 +2501,7 @@ int ie_parse_network_cost(const void *data, size_t len,
}
int ie_parse_owe_transition(const void *data, size_t len,
uint8_t bssid[static 6],
uint8_t ssid[static 32],
size_t *ssid_len)
struct ie_owe_transition_info *info)
{
const uint8_t *ie = data;
size_t slen;
@ -2535,10 +2533,10 @@ int ie_parse_owe_transition(const void *data, size_t len,
if (len != slen + 13)
return -ENOMSG;
memcpy(bssid, ie + 6, 6);
memcpy(info->bssid, ie + 6, 6);
memcpy(ssid, ie + 13, slen);
*ssid_len = slen;
memcpy(info->ssid, ie + 13, slen);
info->ssid_len = slen;
return 0;
}

View File

@ -640,6 +640,4 @@ int ie_parse_network_cost(const void *data, size_t len,
uint16_t *flags, uint16_t *level);
int ie_parse_owe_transition(const void *data, size_t len,
uint8_t bssid[static 6],
uint8_t ssid[static 32],
size_t *ssid_len);
struct ie_owe_transition_info *info);

View File

@ -1110,11 +1110,6 @@ const struct l_queue_entry *network_bss_list_get_entries(
return l_queue_get_entries(network->bss_list);
}
static bool bss_is_owe(struct scan_bss *bss)
{
return !l_memeqzero(bss->owe_trans_bssid, 6) && bss->rsne;
}
struct scan_bss *network_bss_select(struct network *network,
bool fallback_to_blacklist)
{
@ -1141,13 +1136,13 @@ struct scan_bss *network_bss_select(struct network *network,
candidate = bss;
/* OWE Transition BSS */
if (!l_memeqzero(bss->owe_trans_bssid, 6)) {
if (!bss->owe_trans) {
/* Don't want to connect to the Open BSS if possible */
if (!bss->rsne)
continue;
/* Candidate is not OWE, set this as new candidate */
if (!bss_is_owe(candidate))
if (!(candidate->owe_trans && candidate->rsne))
candidate = bss;
}

View File

@ -686,8 +686,8 @@ static void add_owe_scan_cmd(struct scan_context *sc, struct scan_request *sr,
} else
params.freqs = freqs;
params.ssid = bss->owe_trans_ssid;
params.ssid_len = bss->owe_trans_ssid_len;
params.ssid = bss->owe_trans->ssid;
params.ssid_len = bss->owe_trans->ssid_len;
params.flush = true;
cmd = scan_build_cmd(sc, ignore_flush, false, &params);
@ -736,14 +736,14 @@ uint32_t scan_owe_hidden(uint64_t wdev_id, struct l_queue *list,
/* First */
if (!ssid) {
ssid = bss->owe_trans_ssid;
ssid_len = bss->owe_trans_ssid_len;
ssid = bss->owe_trans->ssid;
ssid_len = bss->owe_trans->ssid_len;
continue;
}
if (ssid_len == bss->owe_trans_ssid_len &&
!memcmp(ssid, bss->owe_trans_ssid,
bss->owe_trans_ssid_len))
if (ssid_len == bss->owe_trans->ssid_len &&
!memcmp(ssid, bss->owe_trans->ssid,
bss->owe_trans->ssid_len))
continue;
same_ssid = false;
@ -1060,9 +1060,14 @@ static void scan_parse_vendor_specific(struct scan_bss *bss, const void *data,
}
if (is_ie_wfa_ie(data, len, IE_WFA_OI_OWE_TRANSITION)) {
ie_parse_owe_transition(data - 2, len + 2, bss->owe_trans_bssid,
bss->owe_trans_ssid,
&bss->owe_trans_ssid_len);
bss->owe_trans = l_new(struct ie_owe_transition_info, 1);
if (ie_parse_owe_transition(data - 2, len + 2,
bss->owe_trans) < 0) {
l_free(bss->owe_trans);
bss->owe_trans = NULL;
}
return;
}
@ -1511,6 +1516,7 @@ void scan_bss_free(struct scan_bss *bss)
l_free(bss->osen);
l_free(bss->rc_ie);
l_free(bss->wfd);
l_free(bss->owe_trans);
switch (bss->source_frame) {
case SCAN_BSS_PROBE_RESP:

View File

@ -22,6 +22,7 @@
struct scan_freq_set;
struct ie_rsn_info;
struct ie_owe_transition_info;
struct p2p_probe_resp;
struct p2p_probe_req;
struct p2p_beacon;
@ -62,6 +63,7 @@ struct scan_bss {
struct p2p_probe_req *p2p_probe_req_info;
struct p2p_beacon *p2p_beacon_info;
};
struct ie_owe_transition_info *owe_trans;
uint8_t mde[3];
uint8_t ssid[32];
uint8_t ssid_len;
@ -76,9 +78,6 @@ struct scan_bss {
uint64_t parent_tsf;
uint8_t *wfd; /* Concatenated WFD IEs */
ssize_t wfd_size; /* Size of Concatenated WFD IEs */
uint8_t owe_trans_ssid[32];
size_t owe_trans_ssid_len;
uint8_t owe_trans_bssid[6];
bool mde_present : 1;
bool cc_present : 1;
bool cap_rm_neighbor_report : 1;

View File

@ -400,8 +400,8 @@ static struct network *station_add_seen_bss(struct station *station,
return NULL;
/* Hidden OWE transition network */
if (security == SECURITY_NONE && bss->rsne &&
!l_memeqzero(bss->owe_trans_bssid, 6)) {
if (security == SECURITY_NONE && bss->rsne && bss->owe_trans) {
struct ie_owe_transition_info *info = bss->owe_trans;
/*
* WiFi Alliance OWE Specification v1.1 - Section 2.2.1:
*
@ -420,18 +420,17 @@ static struct network *station_add_seen_bss(struct station *station,
* we could not look up the network. Note that this is not true
* for the open BSS IE, it can be non-utf8.
*/
if (!util_ssid_is_utf8(bss->owe_trans_ssid_len,
bss->owe_trans_ssid))
if (!util_ssid_is_utf8(info->ssid_len, info->ssid))
return NULL;
if (!memcmp(bss->owe_trans_ssid, bss->ssid, bss->ssid_len))
if (!memcmp(info->ssid, bss->ssid, bss->ssid_len))
return NULL;
if (!memcmp(bss->owe_trans_bssid, bss->addr, 6))
if (!memcmp(info->bssid, bss->addr, 6))
return NULL;
memcpy(ssid, bss->owe_trans_ssid, sizeof(bss->owe_trans_ssid));
ssid[bss->owe_trans_ssid_len] = '\0';
memcpy(ssid, info->ssid, info->ssid_len);
ssid[info->ssid_len] = '\0';
l_debug("Found hidden OWE network, using %s for network lookup",
ssid);
@ -690,10 +689,12 @@ static bool station_start_anqp(struct station *station, struct network *network,
static bool network_has_open_pair(struct network *network, struct scan_bss *owe)
{
const struct l_queue_entry *entry;
struct ie_owe_transition_info *owe_info = owe->owe_trans;
for (entry = network_bss_list_get_entries(network); entry;
entry = entry->next) {
struct scan_bss *open = entry->data;
struct ie_owe_transition_info *open_info = open->owe_trans;
/*
* Check if this is an Open/Hidden pair:
@ -704,14 +705,14 @@ static bool network_has_open_pair(struct network *network, struct scan_bss *owe)
* OWE SSID equals the SSID in Open IE
* OWE BSSID equals the BSSID in Open IE
*/
if (open->ssid_len == owe->owe_trans_ssid_len &&
open->owe_trans_ssid_len == owe->ssid_len &&
!memcmp(open->ssid, owe->owe_trans_ssid,
if (open->ssid_len == owe_info->ssid_len &&
open_info->ssid_len == owe->ssid_len &&
!memcmp(open->ssid, owe_info->ssid,
open->ssid_len) &&
!memcmp(open->owe_trans_ssid, owe->ssid,
!memcmp(open_info->ssid, owe->ssid,
owe->ssid_len) &&
!memcmp(open->addr, owe->owe_trans_bssid, 6) &&
!memcmp(open->owe_trans_bssid, owe->addr, 6))
!memcmp(open->addr, owe_info->bssid, 6) &&
!memcmp(open_info->bssid, owe->addr, 6))
return true;
}
@ -736,10 +737,10 @@ static bool station_owe_transition_results(int err, struct l_queue *bss_list,
* Don't handle the open BSS, hidden BSS, BSS with no OWE
* Transition IE, or an IE with a non-utf8 SSID
*/
if (!bss->rsne || l_memeqzero(bss->owe_trans_bssid, 6) ||
if (!bss->rsne || !bss->owe_trans ||
util_ssid_is_hidden(bss->ssid_len, bss->ssid) ||
!util_ssid_is_utf8(bss->owe_trans_ssid_len,
bss->owe_trans_ssid))
!util_ssid_is_utf8(bss->owe_trans->ssid_len,
bss->owe_trans->ssid))
goto free;
@ -807,7 +808,7 @@ static void foreach_add_owe_scan(struct network *network, void *data)
entry = entry->next) {
struct scan_bss *open = entry->data;
if (l_memeqzero(open->owe_trans_bssid, 6))
if (!open->owe_trans)
continue;
/* only want the open networks with WFA OWE IE */
@ -815,7 +816,7 @@ static void foreach_add_owe_scan(struct network *network, void *data)
continue;
/* BSS already in network object */
if (network_bss_find_by_addr(network, open->owe_trans_bssid))
if (network_bss_find_by_addr(network, open->owe_trans->bssid))
continue;
if (!list)
@ -3037,7 +3038,7 @@ static bool station_hidden_network_scan_results(int err,
memcmp(bss->ssid, ssid, ssid_len))
goto next;
if (!l_memeqzero(bss->owe_trans_bssid, 6))
if (bss->owe_trans)
goto next;
/*
@ -3134,7 +3135,7 @@ static struct l_dbus_message *station_dbus_connect_hidden_network(
struct scan_bss *target = network_bss_select(network, true);
/* Treat OWE transition networks special */
if (!l_memeqzero(target->owe_trans_bssid, 6))
if (target->owe_trans)
goto not_hidden;
for (; entry; entry = entry->next) {