bsd: Enable auto configuration

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 :(
This commit is contained in:
Masashi Honma 2010-02-08 21:14:22 +02:00 committed by Jouni Malinen
parent 82f36163ac
commit 5197244a04

View file

@ -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 @@ bsd_set_ssid(int s, const char *ifname, const u8 *ssid, size_t ssid_len)
#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
@ -758,6 +808,32 @@ hostapd_bsd_set_ssid(const char *ifname, void *priv, const u8 *buf, int len)
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)
{
@ -788,6 +864,13 @@ bsd_init(struct hostapd_data *hapd, struct wpa_init_params *params)
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)
@ -831,6 +914,7 @@ const struct wpa_driver_ops wpa_driver_bsd_ops = {
.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 */
@ -1465,6 +1549,13 @@ wpa_driver_bsd_init(void *ctx, const char *ifname)
__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));