summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/wpa/wpa_supplicant/driver_freebsd.c124
1 files changed, 87 insertions, 37 deletions
diff --git a/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c b/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c
index 1a9a0fd..860d8cb 100644
--- a/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c
+++ b/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c
@@ -26,6 +26,7 @@
#include "eloop.h"
#include "wpa_supplicant.h"
#include "l2_packet.h"
+#include "wpa.h" /* XXX for RSN_INFO_ELEM */
#include <sys/socket.h>
#include <net/if.h>
@@ -179,8 +180,6 @@ wpa_driver_bsd_set_wpa(void *priv, int enabled)
if (!enabled && wpa_driver_bsd_set_wpa_ie(drv, NULL, 0) < 0)
ret = -1;
- if (set80211param(drv, IEEE80211_IOC_ROAMING, enabled ? 2 : 0) < 0)
- ret = -1;
if (set80211param(drv, IEEE80211_IOC_PRIVACY, enabled) < 0)
ret = -1;
if (set80211param(drv, IEEE80211_IOC_WPA, enabled ? 3 : 0) < 0)
@@ -195,7 +194,7 @@ wpa_driver_bsd_del_key(struct wpa_driver_bsd_data *drv, int key_idx,
{
struct ieee80211req_del_key wk;
- wpa_printf(MSG_DEBUG, "%s: keyidx=%d", __FUNCTION__, key_idx);
+ wpa_printf(MSG_DEBUG, "%s: keyidx=%d", __func__, key_idx);
memset(&wk, 0, sizeof(wk));
wk.idk_keyix = key_idx;
if (addr != NULL)
@@ -233,22 +232,22 @@ wpa_driver_bsd_set_key(void *priv, wpa_alg alg,
break;
default:
wpa_printf(MSG_DEBUG, "%s: unknown/unsupported algorithm %d",
- __FUNCTION__, alg);
+ __func__, alg);
return -1;
}
wpa_printf(MSG_DEBUG, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%d "
- "key_len=%d", __FUNCTION__, alg_name, key_idx, set_tx,
+ "key_len=%d", __func__, alg_name, key_idx, set_tx,
seq_len, key_len);
if (seq_len > sizeof(u_int64_t)) {
wpa_printf(MSG_DEBUG, "%s: seq_len %d too big",
- __FUNCTION__, seq_len);
+ __func__, seq_len);
return -2;
}
if (key_len > sizeof(wk.ik_keydata)) {
wpa_printf(MSG_DEBUG, "%s: key length %d too big",
- __FUNCTION__, key_len);
+ __func__, key_len);
return -3;
}
@@ -273,7 +272,7 @@ wpa_driver_bsd_set_countermeasures(void *priv, int enabled)
{
struct wpa_driver_bsd_data *drv = priv;
- wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
+ wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
return set80211param(drv, IEEE80211_IOC_COUNTERMEASURES, enabled);
}
@@ -283,7 +282,7 @@ wpa_driver_bsd_set_drop_unencrypted(void *priv, int enabled)
{
struct wpa_driver_bsd_data *drv = priv;
- wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
+ wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
return set80211param(drv, IEEE80211_IOC_DROPUNENCRYPTED, enabled);
}
@@ -293,7 +292,7 @@ wpa_driver_bsd_deauthenticate(void *priv, const u8 *addr, int reason_code)
struct wpa_driver_bsd_data *drv = priv;
struct ieee80211req_mlme mlme;
- wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
+ wpa_printf(MSG_DEBUG, "%s", __func__);
mlme.im_op = IEEE80211_MLME_DEAUTH;
mlme.im_reason = reason_code;
memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
@@ -306,7 +305,7 @@ wpa_driver_bsd_disassociate(void *priv, const u8 *addr, int reason_code)
struct wpa_driver_bsd_data *drv = priv;
struct ieee80211req_mlme mlme;
- wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
+ wpa_printf(MSG_DEBUG, "%s", __func__);
mlme.im_op = IEEE80211_MLME_DISASSOC;
mlme.im_reason = reason_code;
memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
@@ -318,30 +317,63 @@ wpa_driver_bsd_associate(void *priv, struct wpa_driver_associate_params *params)
{
struct wpa_driver_bsd_data *drv = priv;
struct ieee80211req_mlme mlme;
+ int privacy;
+
+ wpa_printf(MSG_DEBUG,
+ "%s: ssid '%.*s' wpa ie len %u pairwise %u group %u key mgmt %u"
+ , __func__
+ , params->ssid_len, params->ssid
+ , params->wpa_ie_len
+ , params->pairwise_suite
+ , params->group_suite
+ , params->key_mgmt_suite
+ );
- int ret = 0;
-
- wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
-
- /*
- * NB: Don't need to set the freq or cipher-related state as
- * this is implied by the bssid which is used to locate
- * the scanned node state which holds it. The ssid is
- * needed to disambiguate an AP that broadcasts multiple
- * ssid's but uses the same bssid.
- */
/* XXX error handling is wrong but unclear what to do... */
if (wpa_driver_bsd_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0)
- ret = -1;
- if (wpa_driver_bsd_set_ssid(drv, params->ssid, params->ssid_len) < 0)
- ret = -1;
+ return -1;
+
+ privacy = !(params->pairwise_suite == CIPHER_NONE &&
+ params->group_suite == CIPHER_NONE &&
+ params->key_mgmt_suite == KEY_MGMT_NONE &&
+ params->wpa_ie_len == 0);
+ wpa_printf(MSG_DEBUG, "%s: set PRIVACY %u", __func__, privacy);
+
+ if (set80211param(drv, IEEE80211_IOC_PRIVACY, privacy) < 0)
+ return -1;
+
+ if (params->wpa_ie_len &&
+ set80211param(drv, IEEE80211_IOC_WPA,
+ params->wpa_ie[0] == RSN_INFO_ELEM ? 2 : 1) < 0)
+ return -1;
+
memset(&mlme, 0, sizeof(mlme));
mlme.im_op = IEEE80211_MLME_ASSOC;
- memcpy(mlme.im_macaddr, params->bssid, IEEE80211_ADDR_LEN);
+ if (params->ssid != NULL)
+ memcpy(mlme.im_ssid, params->ssid, params->ssid_len);
+ mlme.im_ssid_len = params->ssid_len;
+ if (params->bssid != NULL)
+ memcpy(mlme.im_macaddr, params->bssid, IEEE80211_ADDR_LEN);
if (set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)) < 0)
- ret = -1;
+ return -1;
+ return 0;
+}
- return ret;
+static int
+wpa_driver_bsd_set_auth_alg(void *priv, int auth_alg)
+{
+ struct wpa_driver_bsd_data *drv = priv;
+ int authmode;
+
+ if ((auth_alg & AUTH_ALG_OPEN_SYSTEM) &&
+ (auth_alg & AUTH_ALG_SHARED_KEY))
+ authmode = IEEE80211_AUTH_AUTO;
+ else if (auth_alg & AUTH_ALG_SHARED_KEY)
+ authmode = IEEE80211_AUTH_SHARED;
+ else
+ authmode = IEEE80211_AUTH_OPEN;
+
+ return set80211param(drv, IEEE80211_IOC_AUTHMODE, authmode);
}
static int
@@ -582,23 +614,35 @@ wpa_driver_bsd_init(void *ctx, const char *ifname)
return NULL;
memset(drv, 0, sizeof(*drv));
drv->sock = socket(PF_INET, SOCK_DGRAM, 0);
- if (drv->sock < 0) {
- free(drv);
- return NULL;
- }
+ if (drv->sock < 0)
+ goto fail1;
drv->route = socket(PF_ROUTE, SOCK_RAW, 0);
- if (drv->route < 0) {
- close(drv->sock);
- free(drv);
- return NULL;
- }
+ if (drv->route < 0)
+ goto fail;
eloop_register_read_sock(drv->route,
wpa_driver_bsd_event_receive, ctx, NULL);
drv->ctx = ctx;
strncpy(drv->ifname, ifname, sizeof(drv->ifname));
+ 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));
+ goto fail;
+ }
+
+ if (set80211param(drv, IEEE80211_IOC_WPA, 1+2) < 0) {
+ wpa_printf(MSG_DEBUG, "%s: failed to enable WPA support %s",
+ __func__, strerror(errno));
+ goto fail;
+ }
+
return drv;
+fail:
+ close(drv->sock);
+fail1:
+ free(drv);
+ return NULL;
}
static void
@@ -611,6 +655,11 @@ wpa_driver_bsd_deinit(void *priv)
if (getifflags(drv, &flags) == 0)
(void) setifflags(drv, flags &~ IFF_UP);
+ wpa_driver_bsd_set_wpa(drv, 0);
+ if (set80211param(drv, IEEE80211_IOC_ROAMING, IEEE80211_ROAMING_DEVICE) < 0)
+ wpa_printf(MSG_DEBUG, "%s: failed to enable driver-based "
+ "roaming", __func__);
+
(void) close(drv->route); /* ioctl socket */
(void) close(drv->sock); /* event socket */
free(drv);
@@ -633,4 +682,5 @@ struct wpa_driver_ops wpa_driver_bsd_ops = {
.deauthenticate = wpa_driver_bsd_deauthenticate,
.disassociate = wpa_driver_bsd_disassociate,
.associate = wpa_driver_bsd_associate,
+ .set_auth_alg = wpa_driver_bsd_set_auth_alg,
};
OpenPOWER on IntegriCloud