aboutsummaryrefslogtreecommitdiffstats
path: root/src/drivers/driver_bsd.c
diff options
context:
space:
mode:
authorRui Paulo <rpaulo@FreeBSD.org>2013-08-07 07:57:10 (GMT)
committerJouni Malinen <j@w1.fi>2013-08-07 07:57:10 (GMT)
commit5dd82c634cb5e24500ac4d1374f806fb37dd88bb (patch)
treef91ab1fd8e12f0cb649b5210422fc25ac88fd680 /src/drivers/driver_bsd.c
parentcb76af8a35a46146fbc324d28b06c50317c7197b (diff)
downloadhostap-5dd82c634cb5e24500ac4d1374f806fb37dd88bb.zip
hostap-5dd82c634cb5e24500ac4d1374f806fb37dd88bb.tar.gz
hostap-5dd82c634cb5e24500ac4d1374f806fb37dd88bb.tar.bz2
bsd: Set IEEE80211_KEY_NOREPLAY in IBSS/AHDEMO mode
Signed-hostap: Rui Paulo <rpaulo@FreeBSD.org>
Diffstat (limited to 'src/drivers/driver_bsd.c')
-rw-r--r--src/drivers/driver_bsd.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/drivers/driver_bsd.c b/src/drivers/driver_bsd.c
index a80a9ac..baf7ae8 100644
--- a/src/drivers/driver_bsd.c
+++ b/src/drivers/driver_bsd.c
@@ -61,10 +61,37 @@ struct bsd_driver_data {
int prev_roaming; /* roaming state to restore on deinit */
int prev_privacy; /* privacy state to restore on deinit */
int prev_wpa; /* wpa state to restore on deinit */
+ enum ieee80211_opmode opmode; /* operation mode */
};
/* Generic functions for hostapd and wpa_supplicant */
+static enum ieee80211_opmode
+get80211opmode(struct bsd_driver_data *drv)
+{
+ struct ifmediareq ifmr;
+
+ (void) memset(&ifmr, 0, sizeof(ifmr));
+ (void) strncpy(ifmr.ifm_name, drv->ifname, sizeof(ifmr.ifm_name));
+
+ if (ioctl(drv->sock, SIOCGIFMEDIA, (caddr_t)&ifmr) >= 0) {
+ if (ifmr.ifm_current & IFM_IEEE80211_ADHOC) {
+ if (ifmr.ifm_current & IFM_FLAG0)
+ return IEEE80211_M_AHDEMO;
+ else
+ return IEEE80211_M_IBSS;
+ }
+ if (ifmr.ifm_current & IFM_IEEE80211_HOSTAP)
+ return IEEE80211_M_HOSTAP;
+ if (ifmr.ifm_current & IFM_IEEE80211_MONITOR)
+ return IEEE80211_M_MONITOR;
+ if (ifmr.ifm_current & IFM_IEEE80211_MBSS)
+ return IEEE80211_M_MBSS;
+ }
+ return IEEE80211_M_STA;
+}
+
+
static int
bsd_set80211(void *priv, int op, int val, const void *arg, int arg_len)
{
@@ -289,6 +316,7 @@ bsd_set_key(const char *ifname, void *priv, enum wpa_alg alg,
size_t seq_len, const u8 *key, size_t key_len)
{
struct ieee80211req_key wk;
+ struct bsd_driver_data *drv = priv;
wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%p key_idx=%d set_tx=%d "
"seq_len=%zu key_len=%zu", __func__, alg, addr, key_idx,
@@ -343,6 +371,14 @@ bsd_set_key(const char *ifname, void *priv, enum wpa_alg alg,
}
if (wk.ik_keyix != IEEE80211_KEYIX_NONE && set_tx)
wk.ik_flags |= IEEE80211_KEY_DEFAULT;
+#ifndef HOSTAPD
+ /*
+ * Ignore replay failures in IBSS and AHDEMO mode.
+ */
+ if (drv->opmode == IEEE80211_M_IBSS ||
+ drv->opmode == IEEE80211_M_AHDEMO)
+ wk.ik_flags |= IEEE80211_KEY_NOREPLAY;
+#endif /* HOSTAPD */
wk.ik_keylen = key_len;
if (seq) {
#ifdef WORDS_BIGENDIAN
@@ -1498,6 +1534,8 @@ wpa_driver_bsd_init(void *ctx, const char *ifname)
if (wpa_driver_bsd_capa(drv))
goto fail;
+ drv->opmode = get80211opmode(drv);
+
return drv;
fail:
close(drv->sock);