Modified algorithm for generating BSSIDs. Always set locally administered bit. Calculate the mask after calculating the BSSIDs. This eliminates the "Invalid BSSID mask" caused when addr & mask != addr. Signed-off-by: Bill Jordan rajant.com> --- Taken from http://permalink.gmane.org/gmane.linux.drivers.hostap/22207 --- src/ap/hostapd.c | 74 ++++++------------------------------------------------ 1 files changed, 8 insertions(+), 66 deletions(-) diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index f4517f8..1dc6b66 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -360,70 +360,26 @@ static int hostapd_validate_bssid_configuration(struct hostapd_iface *iface) { u8 mask[ETH_ALEN] = { 0 }; struct hostapd_data *hapd = iface->bss[0]; - unsigned int i = iface->conf->num_bss, bits = 0, j; + unsigned int i, j; int res; - int auto_addr = 0; if (hostapd_drv_none(hapd)) return 0; /* Generate BSSID mask that is large enough to cover the BSSIDs. */ - /* Determine the bits necessary to cover the number of BSSIDs. */ - for (i--; i; i >>= 1) - bits++; - /* Determine the bits necessary to any configured BSSIDs, if they are higher than the number of BSSIDs. */ for (j = 0; j < iface->conf->num_bss; j++) { - if (hostapd_mac_comp_empty(iface->conf->bss[j].bssid) == 0) { - if (j) - auto_addr++; - continue; - } - for (i = 0; i < ETH_ALEN; i++) { mask[i] |= - iface->conf->bss[j].bssid[i] ^ + iface->bss[j]->conf->bssid[i] ^ hapd->own_addr[i]; } } - if (!auto_addr) - goto skip_mask_ext; - - for (i = 0; i < ETH_ALEN && mask[i] == 0; i++) - ; - j = 0; - if (i < ETH_ALEN) { - j = (5 - i) * 8; - - while (mask[i] != 0) { - mask[i] >>= 1; - j++; - } - } - - if (bits < j) - bits = j; - - if (bits > 40) { - wpa_printf(MSG_ERROR, "Too many bits in the BSSID mask (%u)", - bits); - return -1; - } - - os_memset(mask, 0xff, ETH_ALEN); - j = bits / 8; - for (i = 5; i > 5 - j; i--) - mask[i] = 0; - j = bits % 8; - while (j--) - mask[i] <<= 1; - -skip_mask_ext: - wpa_printf(MSG_DEBUG, "BSS count %lu, BSSID mask " MACSTR " (%d bits)", - (unsigned long) iface->conf->num_bss, MAC2STR(mask), bits); + wpa_printf(MSG_DEBUG, "BSS count %lu, BSSID mask " MACSTR , + (unsigned long) iface->conf->num_bss, MAC2STR(mask)); res = hostapd_valid_bss_mask(hapd, hapd->own_addr, mask); if (res == 0) @@ -436,21 +392,6 @@ skip_mask_ext: return -1; } - if (!auto_addr) - return 0; - - for (i = 0; i < ETH_ALEN; i++) { - if ((hapd->own_addr[i] & mask[i]) != hapd->own_addr[i]) { - wpa_printf(MSG_ERROR, "Invalid BSSID mask " MACSTR - " for start address " MACSTR ".", - MAC2STR(mask), MAC2STR(hapd->own_addr)); - wpa_printf(MSG_ERROR, "Start address must be the " - "first address in the block (i.e., addr " - "AND mask == addr)."); - return -1; - } - } - return 0; } @@ -492,6 +433,7 @@ static int hostapd_setup_bss(struct hostapd_data *hapd, int first) if (!first) { if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0) { /* Allocate the next available BSSID. */ + hapd->own_addr[0] |= 2; /* locally administered address */ do { inc_byte_array(hapd->own_addr, ETH_ALEN); } while (mac_in_conf(hapd->iconf, hapd->own_addr)); @@ -672,9 +614,6 @@ static int setup_interface(struct hostapd_iface *iface) iface->bss[i]->drv_priv = hapd->drv_priv; } - if (hostapd_validate_bssid_configuration(iface)) - return -1; - if (hapd->iconf->country[0] && hapd->iconf->country[1]) { os_memcpy(country, hapd->iconf->country, 3); country[3] = '\0'; @@ -774,6 +713,9 @@ int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err) prev_addr = hapd->own_addr; } + if (hostapd_validate_bssid_configuration(iface)) + return -1; + hostapd_tx_queue_params(iface); ap_list_init(iface);