diff options
author | Phil Sutter <phil.sutter@viprinet.com> | 2012-01-12 19:36:26 +0100 |
---|---|---|
committer | Waldemar Brodkorb <wbx@openadk.org> | 2012-01-15 11:04:07 +0100 |
commit | 1006235818897c890b4d5cb47a9d78b9c7135fe9 (patch) | |
tree | acfd4eb1d027cae00e9001436b2059643a01cd57 /package/hostapd | |
parent | 6eb624f2ea2133cfb5d8f9a6e8633c386a75a8f9 (diff) |
hostapd: fix for "Invalid BSSID mask" error message
Diffstat (limited to 'package/hostapd')
-rw-r--r-- | package/hostapd/patches/001-fix-bssid-generation.patch | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/package/hostapd/patches/001-fix-bssid-generation.patch b/package/hostapd/patches/001-fix-bssid-generation.patch new file mode 100644 index 000000000..ca328e5aa --- /dev/null +++ b/package/hostapd/patches/001-fix-bssid-generation.patch @@ -0,0 +1,141 @@ +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 <bjordan <at> 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); |