001-fix-bssid-generation.patch 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. Modified algorithm for generating BSSIDs. Always set locally
  2. administered bit. Calculate the mask after calculating the
  3. BSSIDs. This eliminates the "Invalid BSSID mask" caused when
  4. addr & mask != addr.
  5. Signed-off-by: Bill Jordan <bjordan <at> rajant.com>
  6. ---
  7. Taken from http://permalink.gmane.org/gmane.linux.drivers.hostap/22207
  8. ---
  9. src/ap/hostapd.c | 74 ++++++------------------------------------------------
  10. 1 files changed, 8 insertions(+), 66 deletions(-)
  11. diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
  12. index f4517f8..1dc6b66 100644
  13. --- a/src/ap/hostapd.c
  14. +++ b/src/ap/hostapd.c
  15. @@ -360,70 +360,26 @@ static int hostapd_validate_bssid_configuration(struct hostapd_iface *iface)
  16. {
  17. u8 mask[ETH_ALEN] = { 0 };
  18. struct hostapd_data *hapd = iface->bss[0];
  19. - unsigned int i = iface->conf->num_bss, bits = 0, j;
  20. + unsigned int i, j;
  21. int res;
  22. - int auto_addr = 0;
  23. if (hostapd_drv_none(hapd))
  24. return 0;
  25. /* Generate BSSID mask that is large enough to cover the BSSIDs. */
  26. - /* Determine the bits necessary to cover the number of BSSIDs. */
  27. - for (i--; i; i >>= 1)
  28. - bits++;
  29. -
  30. /* Determine the bits necessary to any configured BSSIDs,
  31. if they are higher than the number of BSSIDs. */
  32. for (j = 0; j < iface->conf->num_bss; j++) {
  33. - if (hostapd_mac_comp_empty(iface->conf->bss[j].bssid) == 0) {
  34. - if (j)
  35. - auto_addr++;
  36. - continue;
  37. - }
  38. -
  39. for (i = 0; i < ETH_ALEN; i++) {
  40. mask[i] |=
  41. - iface->conf->bss[j].bssid[i] ^
  42. + iface->bss[j]->conf->bssid[i] ^
  43. hapd->own_addr[i];
  44. }
  45. }
  46. - if (!auto_addr)
  47. - goto skip_mask_ext;
  48. -
  49. - for (i = 0; i < ETH_ALEN && mask[i] == 0; i++)
  50. - ;
  51. - j = 0;
  52. - if (i < ETH_ALEN) {
  53. - j = (5 - i) * 8;
  54. -
  55. - while (mask[i] != 0) {
  56. - mask[i] >>= 1;
  57. - j++;
  58. - }
  59. - }
  60. -
  61. - if (bits < j)
  62. - bits = j;
  63. -
  64. - if (bits > 40) {
  65. - wpa_printf(MSG_ERROR, "Too many bits in the BSSID mask (%u)",
  66. - bits);
  67. - return -1;
  68. - }
  69. -
  70. - os_memset(mask, 0xff, ETH_ALEN);
  71. - j = bits / 8;
  72. - for (i = 5; i > 5 - j; i--)
  73. - mask[i] = 0;
  74. - j = bits % 8;
  75. - while (j--)
  76. - mask[i] <<= 1;
  77. -
  78. -skip_mask_ext:
  79. - wpa_printf(MSG_DEBUG, "BSS count %lu, BSSID mask " MACSTR " (%d bits)",
  80. - (unsigned long) iface->conf->num_bss, MAC2STR(mask), bits);
  81. + wpa_printf(MSG_DEBUG, "BSS count %lu, BSSID mask " MACSTR ,
  82. + (unsigned long) iface->conf->num_bss, MAC2STR(mask));
  83. res = hostapd_valid_bss_mask(hapd, hapd->own_addr, mask);
  84. if (res == 0)
  85. @@ -436,21 +392,6 @@ skip_mask_ext:
  86. return -1;
  87. }
  88. - if (!auto_addr)
  89. - return 0;
  90. -
  91. - for (i = 0; i < ETH_ALEN; i++) {
  92. - if ((hapd->own_addr[i] & mask[i]) != hapd->own_addr[i]) {
  93. - wpa_printf(MSG_ERROR, "Invalid BSSID mask " MACSTR
  94. - " for start address " MACSTR ".",
  95. - MAC2STR(mask), MAC2STR(hapd->own_addr));
  96. - wpa_printf(MSG_ERROR, "Start address must be the "
  97. - "first address in the block (i.e., addr "
  98. - "AND mask == addr).");
  99. - return -1;
  100. - }
  101. - }
  102. -
  103. return 0;
  104. }
  105. @@ -492,6 +433,7 @@ static int hostapd_setup_bss(struct hostapd_data *hapd, int first)
  106. if (!first) {
  107. if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0) {
  108. /* Allocate the next available BSSID. */
  109. + hapd->own_addr[0] |= 2; /* locally administered address */
  110. do {
  111. inc_byte_array(hapd->own_addr, ETH_ALEN);
  112. } while (mac_in_conf(hapd->iconf, hapd->own_addr));
  113. @@ -672,9 +614,6 @@ static int setup_interface(struct hostapd_iface *iface)
  114. iface->bss[i]->drv_priv = hapd->drv_priv;
  115. }
  116. - if (hostapd_validate_bssid_configuration(iface))
  117. - return -1;
  118. -
  119. if (hapd->iconf->country[0] && hapd->iconf->country[1]) {
  120. os_memcpy(country, hapd->iconf->country, 3);
  121. country[3] = '\0';
  122. @@ -774,6 +713,9 @@ int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err)
  123. prev_addr = hapd->own_addr;
  124. }
  125. + if (hostapd_validate_bssid_configuration(iface))
  126. + return -1;
  127. +
  128. hostapd_tx_queue_params(iface);
  129. ap_list_init(iface);