[PATCH] bsd: Enable auto configuration

Masashi Honma honma
Wed Jan 27 00:50:16 PST 2010


Hello.

On NetBSD, we should configure some parameters manually out of hostapd
like below.

# ifconfig ath0 mediaopt hostap
# ifconfig ath0 mode 11g
# ifconfig ath0 chan 6

This patch does these automatically. Maybe there will be some
objections, like "hardware configuration is not hostapd/wpa_supplican's
work". So I will write the reasons why I made this patch.

1. For usability.
2. The first command fails when previous state is adhoc. This patch is
free from previous state.
3. Some driver wrappers configure these automatically (like nl80211).
4. I have wasted time trying to find out these command were needed :(


--- driver_bsd.c.bak	2010-01-27 17:47:36.000000000 +0900
+++ driver_bsd.c	2010-01-27 17:47:35.000000000 +0900
@@ -22,6 +22,7 @@
 #include "common/ieee802_11_defs.h"
 
 #include <net/if.h>
+#include <net/if_media.h>
 
 #ifdef __NetBSD__
 #include <net/if_ether.h>
@@ -142,6 +143,55 @@
 #endif
 }
 
+static int
+bsd_get_if_media(int s, const char *ifname)
+{
+	struct ifmediareq ifmr;
+
+	os_memset(&ifmr, 0, sizeof(ifmr));
+	os_strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name));
+
+	if (ioctl(s, SIOCGIFMEDIA, &ifmr) < 0) {
+		wpa_printf(MSG_ERROR, "%s: SIOCGIFMEDIA %s", __func__,
+			   strerror(errno));
+		return -1;
+	}
+
+	return ifmr.ifm_current;
+}
+
+static int
+bsd_set_if_media(int s, const char *ifname, int media)
+{
+	struct ifreq ifr;
+
+	os_memset(&ifr, 0, sizeof(ifr));
+	os_strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+	ifr.ifr_media = media;
+
+	if (ioctl(s, SIOCSIFMEDIA, &ifr) < 0) {
+		wpa_printf(MSG_ERROR, "%s: SIOCSIFMEDIA %s", __func__,
+			   strerror(errno));
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+bsd_set_mediaopt(int s, const char *ifname, uint32_t mask, uint32_t mode)
+{
+	int media = bsd_get_if_media(s, ifname);
+
+	if (media < 0)
+		return -1;
+	media &= ~mask;
+	media |= mode;
+	if (bsd_set_if_media(s, ifname, media) < 0)
+		return -1;
+	return 0;
+}
+
 
 #ifdef HOSTAPD
 
@@ -732,6 +782,32 @@
 	return bsd_set_ssid(drv->ioctl_sock, drv->iface, buf, len);
 }
 
+static int
+bsd_set_freq(void *priv, struct hostapd_freq_params *freq)
+{
+	struct bsd_driver_data *drv = priv;
+	struct ieee80211chanreq creq;
+	uint32_t mode;
+
+	if (freq->channel < 14)
+		mode = IFM_IEEE80211_11G;
+	else if (freq->channel == 14)
+		mode = IFM_IEEE80211_11B;
+	else
+		mode = IFM_IEEE80211_11A;
+	if (bsd_set_mediaopt(drv->ioctl_sock, drv->iface, IFM_MMASK,
+			     mode) < 0) {
+		wpa_printf(MSG_ERROR, "%s: failed to set modulation mode",
+			   __func__);
+		return -1;
+	}
+
+	os_memset(&creq, 0, sizeof(creq));
+	os_strlcpy(creq.i_name, drv->iface, sizeof(creq.i_name));
+	creq.i_channel = freq->channel;
+	return ioctl(drv->ioctl_sock, SIOCS80211CHANNEL, &creq);
+}
+
 static void *
 bsd_init(struct hostapd_data *hapd, struct wpa_init_params *params)
 {
@@ -762,6 +838,13 @@
 	if (bsd_wireless_event_init(drv))
 		goto bad;
 
+	if (bsd_set_mediaopt(drv->ioctl_sock, drv->iface, IFM_OMASK,
+			     IFM_IEEE80211_HOSTAP) < 0) {
+		wpa_printf(MSG_ERROR, "%s: failed to set operation mode",
+			   __func__);
+		goto bad;
+	}
+
 	return drv;
 bad:
 	if (drv->sock_xmit != NULL)
@@ -805,6 +888,7 @@
 	.sta_deauth		= bsd_sta_deauth,
 	.hapd_set_ssid		= hostapd_bsd_set_ssid,
 	.hapd_get_ssid		= hostapd_bsd_get_ssid,
+	.set_freq		= bsd_set_freq,
 };
 
 #else /* HOSTAPD */
@@ -1439,6 +1523,13 @@
 			__func__, strerror(errno));
 		goto fail;
 	}
+
+	if (bsd_set_mediaopt(drv->sock, drv->ifname, IFM_OMASK,
+			     0 /* STA */) < 0) {
+		wpa_printf(MSG_ERROR, "%s: failed to set operation mode",
+			   __func__);
+		goto fail;
+	}
 	if (set80211param(drv, IEEE80211_IOC_ROAMING, IEEE80211_ROAMING_MANUAL) < 0) {
 		wpa_printf(MSG_DEBUG, "%s: failed to set wpa_supplicant-based "
 			   "roaming: %s", __func__, strerror(errno));


Regards,
Masashi Honma.



More information about the Hostap mailing list