[PATCH] hostapd: allow bssid config on default interface

Johannes Berg johannes at sipsolutions.net
Wed Dec 12 11:38:03 EST 2007


This patch makes hostapd accept bssid= on the default interface for
those drivers that are changed to support it and changes
driver_devicescape to support it. In order to support such a setting the
driver must provide an init_bssid() in addition to the init() routine.

Signed-off-by: Johannes Berg <johannes at sipsolutions.net>
---
The reason I want this is that I'm lazy and because the default MAC
address of my interface is odd (lowest bit set) hostapd rejects the
configuration if I don't clear that bit by hand... specifying it in the
config file makes it much easier.

Other drivers could easily support it too but again I'm too lazy...

 hostapd/config.c             |    6 ++++--
 hostapd/driver.h             |    9 +++++++++
 hostapd/driver_devicescape.c |   28 ++++++++++++++++++++++++----
 hostapd/hostapd.c            |    8 +++++++-
 4 files changed, 44 insertions(+), 7 deletions(-)

--- hostap.orig/hostapd/driver.h	2007-12-12 17:27:56.000000000 +0100
+++ hostap/hostapd/driver.h	2007-12-12 17:29:03.000000000 +0100
@@ -23,6 +23,7 @@ struct wpa_driver_ops {
 	const char *name;		/* as appears in the config file */
 
 	void * (*init)(struct hostapd_data *hapd);
+	void * (*init_bssid)(struct hostapd_data *hapd, u8 *bssid);
 	void (*deinit)(void *priv);
 
 	int (*wireless_event_init)(void *priv);
@@ -168,6 +169,14 @@ hostapd_driver_init(struct hostapd_data 
 	return hapd->driver->init(hapd);
 }
 
+static inline void *
+hostapd_driver_init_bssid(struct hostapd_data *hapd, u8 *bssid)
+{
+	if (hapd->driver == NULL || hapd->driver->init_bssid == NULL)
+		return NULL;
+	return hapd->driver->init_bssid(hapd, bssid);
+}
+
 static inline void
 hostapd_driver_deinit(struct hostapd_data *hapd)
 {
--- hostap.orig/hostapd/config.c	2007-12-12 17:27:56.000000000 +0100
+++ hostap/hostapd/config.c	2007-12-12 17:29:03.000000000 +0100
@@ -1891,9 +1891,11 @@ struct hostapd_config * hostapd_config_r
 				errors++;
 			}
 		} else if (os_strcmp(buf, "bssid") == 0) {
-			if (bss == conf->bss) {
+			if (bss == conf->bss &&
+			    (!conf->driver || !conf->driver->init_bssid)) {
 				printf("Line %d: bssid item not allowed "
-				       "for the default interface\n", line);
+				       "for the default interface and this "
+				       "driver\n", line);
 				errors++;
 			} else if (hwaddr_aton(pos, bss->bssid)) {
 				printf("Line %d: invalid bssid item\n", line);
--- hostap.orig/hostapd/hostapd.c	2007-12-12 17:27:56.000000000 +0100
+++ hostap/hostapd/hostapd.c	2007-12-12 17:29:03.000000000 +0100
@@ -1468,12 +1468,18 @@ static int setup_interface1(struct hosta
 	struct hostapd_bss_config *conf = hapd->conf;
 	size_t i;
 	char country[4];
+	u8 *b = conf->bssid;
 
 	/*
 	 * Initialize the driver interface and make sure that all BSSes get
 	 * configured with a pointer to this driver interface.
 	 */
-	hapd->drv_priv = hostapd_driver_init(hapd);
+	if (b[0] | b[1] | b[2] | b[3] | b[4] | b[5]) {
+		hapd->drv_priv = hostapd_driver_init_bssid(hapd, b);
+	} else {
+		hapd->drv_priv = hostapd_driver_init(hapd);
+	}
+
 	if (hapd->drv_priv == NULL) {
 		printf("%s driver initialization failed.\n",
 			hapd->driver ? hapd->driver->name : "Unknown");
--- hostap.orig/hostapd/driver_devicescape.c	2007-12-12 17:29:00.000000000 +0100
+++ hostap/hostapd/driver_devicescape.c	2007-12-12 17:29:03.000000000 +0100
@@ -1499,7 +1499,7 @@ static void handle_read(int sock, void *
 }
 
 
-static int i802_init_sockets(struct i802_driver_data *drv)
+static int i802_init_sockets(struct i802_driver_data *drv, u8 *bssid)
 {
 	struct hostapd_data *hapd = drv->hapd;
 	struct hostapd_iface *iface = hapd->iface;
@@ -1515,6 +1515,20 @@ static int i802_init_sockets(struct i802
 		return -1;
 	}
 
+	if (hostapd_set_iface_flags(drv, drv->iface, 0))
+		return -1;
+
+	if (bssid) {
+		os_strlcpy(ifr.ifr_name, drv->iface, IFNAMSIZ);
+		memcpy(ifr.ifr_hwaddr.sa_data, bssid, ETH_ALEN);
+		ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
+
+		if (ioctl(drv->ioctl_sock, SIOCSIFHWADDR, &ifr)) {
+			perror("ioctl(SIOCSIFHWADDR)");
+			return -1;
+		}
+	}
+
 	/*
 	 * initialise generic netlink and nl80211
 	 */
@@ -1928,8 +1942,7 @@ static int i802_sta_disassoc(void *priv,
 				       sizeof(mgmt.u.disassoc), 0);
 }
 
-
-static void * i802_init(struct hostapd_data *hapd)
+static void *i802_init_bssid(struct hostapd_data *hapd, u8 *bssid)
 {
 	struct i802_driver_data *drv;
 
@@ -1942,7 +1955,7 @@ static void * i802_init(struct hostapd_d
 	drv->hapd = hapd;
 	memcpy(drv->iface, hapd->conf->iface, sizeof(drv->iface));
 
-	if (i802_init_sockets(drv))
+	if (i802_init_sockets(drv, bssid))
 		goto failed;
 
 	return drv;
@@ -1953,6 +1966,12 @@ failed:
 }
 
 
+static void *i802_init(struct hostapd_data *hapd)
+{
+	return i802_init_bssid(hapd, NULL);
+}
+
+
 static void i802_deinit(void *priv)
 {
 	struct i802_driver_data *drv = priv;
@@ -1980,6 +1999,7 @@ static void i802_deinit(void *priv)
 const struct wpa_driver_ops wpa_driver_devicescape_ops = {
 	.name = "devicescape",
 	.init = i802_init,
+	.init_bssid = i802_init_bssid,
 	.deinit = i802_deinit,
 	.wireless_event_init = i802_wireless_event_init,
 	.wireless_event_deinit = i802_wireless_event_deinit,





More information about the HostAP mailing list