From: John Crispin Date: Tue, 27 Jul 2021 23:42:20 +0000 (-0700) Subject: RNR: Add data from neighbor database X-Git-Tag: hostap_2_10~70 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a7c152d6b8065e3b2c3c0b3562e8a22e53d60f2e;p=thirdparty%2Fhostap.git RNR: Add data from neighbor database Include data from the existing neighbor database in the Reduced Neighbor Report element in Beacon frames if the configuration option 'rnr' is enabled for the BSS. Signed-off-by: John Crispin Signed-off-by: Muna Sinada Co-developed-by: Aloka Dixit Signed-off-by: Aloka Dixit --- diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 71fbefc8e..52df06d29 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -7071,4 +7071,129 @@ u8 * hostapd_eid_wb_chsw_wrapper(struct hostapd_data *hapd, u8 *eid) return eid; } + +static size_t hostapd_eid_nr_db_len(struct hostapd_data *hapd, + size_t *current_len) +{ + struct hostapd_neighbor_entry *nr; + size_t total_len = 0, len = *current_len; + + dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry, + list) { + if (!nr->nr || wpabuf_len(nr->nr) < 12) + continue; + + if (nr->short_ssid == hapd->conf->ssid.short_ssid) + continue; + + /* Start a new element */ + if (!len || + len + RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN > 255) { + len = RNR_HEADER_LEN; + total_len += RNR_HEADER_LEN; + } + + len += RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN; + total_len += RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN; + } + + *current_len = len; + return total_len; +} + + +size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type) +{ + size_t total_len = 0, current_len = 0; + + switch (type) { + case WLAN_FC_STYPE_BEACON: + if (hapd->conf->rnr) + total_len += hostapd_eid_nr_db_len(hapd, ¤t_len); + break; + + default: + break; + } + + return total_len; +} + + +static u8 * hostapd_eid_nr_db(struct hostapd_data *hapd, u8 *eid, + size_t *current_len) +{ + struct hostapd_neighbor_entry *nr; + size_t len = *current_len; + u8 *size_offset = (eid - len) + 1; + + dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry, + list) { + if (!nr->nr || wpabuf_len(nr->nr) < 12) + continue; + + if (nr->short_ssid == hapd->conf->ssid.short_ssid) + continue; + + /* Start a new element */ + if (!len || + len + RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN > 255) { + *eid++ = WLAN_EID_REDUCED_NEIGHBOR_REPORT; + size_offset = eid++; + len = RNR_HEADER_LEN; + } + + /* TBTT Information Header subfield (2 octets) */ + *eid++ = 0; + /* TBTT Information Length */ + *eid++ = RNR_TBTT_INFO_LEN; + /* Operating Class */ + *eid++ = wpabuf_head_u8(nr->nr)[10]; + /* Channel Number */ + *eid++ = wpabuf_head_u8(nr->nr)[11]; + len += RNR_TBTT_HEADER_LEN; + /* TBTT Information Set */ + /* TBTT Information field */ + /* Neighbor AP TBTT Offset */ + *eid++ = RNR_NEIGHBOR_AP_OFFSET_UNKNOWN; + /* BSSID */ + os_memcpy(eid, nr->bssid, ETH_ALEN); + eid += ETH_ALEN; + /* Short SSID */ + os_memcpy(eid, &nr->short_ssid, 4); + eid += 4; + /* BSS parameters */ + *eid++ = nr->bss_parameters; + /* 20 MHz PSD */ + *eid++ = RNR_20_MHZ_PSD_MAX_TXPOWER - 1; + len += RNR_TBTT_INFO_LEN; + *size_offset = (eid - size_offset) - 1; + } + + *current_len = len; + return eid; +} + + +u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type) +{ + u8 *eid_start = eid; + size_t current_len = 0; + + switch (type) { + case WLAN_FC_STYPE_BEACON: + if (hapd->conf->rnr) + eid = hostapd_eid_nr_db(hapd, eid, ¤t_len); + break; + + default: + return eid_start; + } + + if (eid == eid_start + 2) + return eid_start; + + return eid; +} + #endif /* CONFIG_NATIVE_WINDOWS */ diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h index ea8c60846..c59ad5e38 100644 --- a/src/ap/ieee802_11.h +++ b/src/ap/ieee802_11.h @@ -194,5 +194,7 @@ int get_tx_parameters(struct sta_info *sta, int ap_max_chanwidth, void auth_sae_process_commit(void *eloop_ctx, void *user_ctx); u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len); +size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type); +u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type); #endif /* IEEE802_11_H */