From 90ac1f9fc9411453d83900c7d1d2e6abfdb65ac3 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 12 Mar 2009 22:01:26 +0200 Subject: [PATCH] Allow more complex BSSID masks to be used for multi-BSSID If every secondary BSS is configured with a pre-set BSSID, hostapd does not enforce the BSSID mask requirements anymore, i.e., they are used only if hostapd is responsible for generating MAC addresses for virtual interfaces. --- hostapd/hostapd.c | 18 ++++++++++++++++-- hostapd/hostapd.conf | 5 ++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/hostapd/hostapd.c b/hostapd/hostapd.c index 8531d0a4a..6a0471369 100644 --- a/hostapd/hostapd.c +++ b/hostapd/hostapd.c @@ -1012,6 +1012,7 @@ static int hostapd_validate_bssid_configuration(struct hostapd_iface *iface) struct hostapd_data *hapd = iface->bss[0]; unsigned int i = iface->conf->num_bss, bits = 0, j; int res; + int auto_addr = 0; if (hostapd_drv_none(hapd)) return 0; @@ -1025,8 +1026,11 @@ static int hostapd_validate_bssid_configuration(struct hostapd_iface *iface) /* 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 (hostapd_mac_comp_empty(iface->conf->bss[j].bssid) == 0) { + if (j) + auto_addr++; continue; + } for (i = 0; i < ETH_ALEN; i++) { mask[i] |= @@ -1035,6 +1039,9 @@ static int hostapd_validate_bssid_configuration(struct hostapd_iface *iface) } } + if (!auto_addr) + goto skip_mask_ext; + for (i = 0; i < ETH_ALEN && mask[i] == 0; i++) ; j = 0; @@ -1050,8 +1057,11 @@ static int hostapd_validate_bssid_configuration(struct hostapd_iface *iface) if (bits < j) bits = j; - if (bits > 40) + 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; @@ -1061,6 +1071,7 @@ static int hostapd_validate_bssid_configuration(struct hostapd_iface *iface) 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); @@ -1075,6 +1086,9 @@ static int hostapd_validate_bssid_configuration(struct hostapd_iface *iface) 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 diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index 0533f19af..117e1d5b3 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -1006,7 +1006,10 @@ own_ip_addr=127.0.0.1 # hostapd will generate BSSID mask based on the BSSIDs that are # configured. hostapd will verify that dev_addr & MASK == dev_addr. If this is # not the case, the MAC address of the radio must be changed before starting -# hostapd (ifconfig wlan0 hw ether ). +# hostapd (ifconfig wlan0 hw ether ). If a BSSID is configured for +# every secondary BSS, this limitation is not applied at hostapd and other +# masks may be used if the driver supports them (e.g., swap the locally +# administered bit) # # BSSIDs are assigned in order to each BSS, unless an explicit BSSID is # specified using the 'bssid' parameter.