summaryrefslogtreecommitdiff
path: root/package/hostapd/patches/001-fix-bssid-generation.patch
blob: ca328e5aa79b91c5d05f9af44973777b49c7883a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
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);