summaryrefslogtreecommitdiffstats
path: root/contrib/wpa/src/drivers/driver_bsd.c
diff options
context:
space:
mode:
authorrpaulo <rpaulo@FreeBSD.org>2015-04-21 01:45:11 +0000
committerrpaulo <rpaulo@FreeBSD.org>2015-04-21 01:45:11 +0000
commit842f4520d0888b29092df5d0d02c98cf458d22f7 (patch)
tree2cc3a30a65916dde45972adbf0d20263dbd38514 /contrib/wpa/src/drivers/driver_bsd.c
parent2b5cce437990f63ca2ad7e2ec6f65e2d91d98f43 (diff)
parent30dc5ae44f65d272ea1e32635149befdbf9833cf (diff)
downloadFreeBSD-src-842f4520d0888b29092df5d0d02c98cf458d22f7.zip
FreeBSD-src-842f4520d0888b29092df5d0d02c98cf458d22f7.tar.gz
Merge wpa_supplicant/hostapd 2.4.
Major changes are: SAE, Suite B, RFC 7268, EAP-PKE, ACS, and tons of bug fixes. Relnotes: yes
Diffstat (limited to 'contrib/wpa/src/drivers/driver_bsd.c')
-rw-r--r--contrib/wpa/src/drivers/driver_bsd.c238
1 files changed, 128 insertions, 110 deletions
diff --git a/contrib/wpa/src/drivers/driver_bsd.c b/contrib/wpa/src/drivers/driver_bsd.c
index d3bca6f..63b0e19 100644
--- a/contrib/wpa/src/drivers/driver_bsd.c
+++ b/contrib/wpa/src/drivers/driver_bsd.c
@@ -62,36 +62,11 @@ struct bsd_driver_data {
int prev_privacy; /* privacy state to restore on deinit */
int prev_wpa; /* wpa state to restore on deinit */
enum ieee80211_opmode opmode; /* operation mode */
+ char *event_buf;
+ size_t event_buf_len;
};
/* 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)
{
@@ -288,7 +263,8 @@ bsd_ctrl_iface(void *priv, int enable)
os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name));
if (ioctl(drv->sock, SIOCGIFFLAGS, &ifr) < 0) {
- perror("ioctl[SIOCGIFFLAGS]");
+ wpa_printf(MSG_ERROR, "ioctl[SIOCGIFFLAGS]: %s",
+ strerror(errno));
return -1;
}
@@ -303,7 +279,8 @@ bsd_ctrl_iface(void *priv, int enable)
}
if (ioctl(drv->sock, SIOCSIFFLAGS, &ifr) < 0) {
- perror("ioctl[SIOCSIFFLAGS]");
+ wpa_printf(MSG_ERROR, "ioctl[SIOCSIFFLAGS]: %s",
+ strerror(errno));
return -1;
}
@@ -311,18 +288,14 @@ bsd_ctrl_iface(void *priv, int enable)
}
static int
-bsd_commit(void *priv)
-{
- return bsd_ctrl_iface(priv, 1);
-}
-
-static int
bsd_set_key(const char *ifname, void *priv, enum wpa_alg alg,
const unsigned char *addr, int key_idx, int set_tx, const u8 *seq,
size_t seq_len, const u8 *key, size_t key_len)
{
struct ieee80211req_key wk;
+#ifdef IEEE80211_KEY_NOREPLAY
struct bsd_driver_data *drv = priv;
+#endif /* IEEE80211_KEY_NOREPLAY */
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,
@@ -378,13 +351,15 @@ 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
+#ifdef IEEE80211_KEY_NOREPLAY
/*
* 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
+#endif /* IEEE80211_KEY_NOREPLAY */
+#endif /* HOSTAPD */
wk.ik_keylen = key_len;
if (seq) {
#ifdef WORDS_BIGENDIAN
@@ -430,22 +405,24 @@ bsd_configure_wpa(void *priv, struct wpa_bss_params *params)
v = IEEE80211_CIPHER_NONE;
break;
default:
- printf("Unknown group key cipher %u\n",
- params->wpa_group);
+ wpa_printf(MSG_INFO, "Unknown group key cipher %u",
+ params->wpa_group);
return -1;
}
wpa_printf(MSG_DEBUG, "%s: group key cipher=%s (%u)",
__func__, ciphernames[v], v);
if (set80211param(priv, IEEE80211_IOC_MCASTCIPHER, v)) {
- printf("Unable to set group key cipher to %u (%s)\n",
- v, ciphernames[v]);
+ wpa_printf(MSG_INFO,
+ "Unable to set group key cipher to %u (%s)",
+ v, ciphernames[v]);
return -1;
}
if (v == IEEE80211_CIPHER_WEP) {
/* key length is done only for specific ciphers */
v = (params->wpa_group == WPA_CIPHER_WEP104 ? 13 : 5);
if (set80211param(priv, IEEE80211_IOC_MCASTKEYLEN, v)) {
- printf("Unable to set group key length to %u\n", v);
+ wpa_printf(MSG_INFO,
+ "Unable to set group key length to %u", v);
return -1;
}
}
@@ -459,7 +436,8 @@ bsd_configure_wpa(void *priv, struct wpa_bss_params *params)
v |= 1<<IEEE80211_CIPHER_NONE;
wpa_printf(MSG_DEBUG, "%s: pairwise key ciphers=0x%x", __func__, v);
if (set80211param(priv, IEEE80211_IOC_UCASTCIPHERS, v)) {
- printf("Unable to set pairwise key ciphers to 0x%x\n", v);
+ wpa_printf(MSG_INFO,
+ "Unable to set pairwise key ciphers to 0x%x", v);
return -1;
}
@@ -467,8 +445,9 @@ bsd_configure_wpa(void *priv, struct wpa_bss_params *params)
__func__, params->wpa_key_mgmt);
if (set80211param(priv, IEEE80211_IOC_KEYMGTALGS,
params->wpa_key_mgmt)) {
- printf("Unable to set key management algorithms to 0x%x\n",
- params->wpa_key_mgmt);
+ wpa_printf(MSG_INFO,
+ "Unable to set key management algorithms to 0x%x",
+ params->wpa_key_mgmt);
return -1;
}
@@ -478,14 +457,15 @@ bsd_configure_wpa(void *priv, struct wpa_bss_params *params)
wpa_printf(MSG_DEBUG, "%s: rsn capabilities=0x%x",
__func__, params->rsn_preauth);
if (set80211param(priv, IEEE80211_IOC_RSNCAPS, v)) {
- printf("Unable to set RSN capabilities to 0x%x\n", v);
+ wpa_printf(MSG_INFO, "Unable to set RSN capabilities to 0x%x",
+ v);
return -1;
}
#endif /* IEEE80211_IOC_APPIE */
wpa_printf(MSG_DEBUG, "%s: enable WPA= 0x%x", __func__, params->wpa);
if (set80211param(priv, IEEE80211_IOC_WPA, params->wpa)) {
- printf("Unable to set WPA to %u\n", params->wpa);
+ wpa_printf(MSG_INFO, "Unable to set WPA to %u", params->wpa);
return -1;
}
return 0;
@@ -520,26 +500,6 @@ bsd_set_ieee8021x(void *priv, struct wpa_bss_params *params)
return bsd_ctrl_iface(priv, 1);
}
-static int
-bsd_set_sta_authorized(void *priv, const u8 *addr,
- int total_flags, int flags_or, int flags_and)
-{
- int authorized = -1;
-
- /* For now, only support setting Authorized flag */
- if (flags_or & WPA_STA_AUTHORIZED)
- authorized = 1;
- if (!(flags_and & WPA_STA_AUTHORIZED))
- authorized = 0;
-
- if (authorized < 0)
- return 0;
-
- return bsd_send_mlme_param(priv, authorized ?
- IEEE80211_MLME_AUTHORIZE :
- IEEE80211_MLME_UNAUTHORIZE, 0, addr);
-}
-
static void
bsd_new_sta(void *priv, void *ctx, u8 addr[IEEE80211_ADDR_LEN])
{
@@ -553,7 +513,8 @@ bsd_new_sta(void *priv, void *ctx, u8 addr[IEEE80211_ADDR_LEN])
memset(&ie, 0, sizeof(ie));
memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN);
if (get80211var(priv, IEEE80211_IOC_WPAIE, &ie, sizeof(ie)) < 0) {
- printf("Failed to get WPA/RSN information element.\n");
+ wpa_printf(MSG_INFO,
+ "Failed to get WPA/RSN information element");
goto no_ie;
}
iebuf = ie.wpa_ie;
@@ -632,7 +593,7 @@ bsd_set_opt_ie(void *priv, const u8 *ie, size_t ie_len)
return 0;
}
-static int
+static size_t
rtbuf_len(void)
{
size_t len;
@@ -640,7 +601,7 @@ rtbuf_len(void)
int mib[6] = {CTL_NET, AF_ROUTE, 0, AF_INET, NET_RT_DUMP, 0};
if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
- wpa_printf(MSG_WARNING, "%s failed: %s\n", __func__,
+ wpa_printf(MSG_WARNING, "%s failed: %s", __func__,
strerror(errno));
len = 2048;
}
@@ -698,7 +659,7 @@ bsd_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx,
wk.ik_keyix = idx;
if (get80211var(priv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk)) < 0) {
- printf("Failed to get encryption.\n");
+ wpa_printf(MSG_INFO, "Failed to get encryption");
return -1;
}
@@ -722,7 +683,7 @@ bsd_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx,
}
-static int
+static int
bsd_flush(void *priv)
{
u8 allsta[IEEE80211_ADDR_LEN];
@@ -769,37 +730,26 @@ static void
bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx)
{
struct bsd_driver_data *drv = ctx;
- char *buf;
struct if_announcemsghdr *ifan;
struct rt_msghdr *rtm;
struct ieee80211_michael_event *mic;
struct ieee80211_join_event *join;
struct ieee80211_leave_event *leave;
- int n, len;
+ int n;
union wpa_event_data data;
- len = rtbuf_len();
-
- buf = os_malloc(len);
- if (buf == NULL) {
- wpa_printf(MSG_ERROR, "%s os_malloc() failed\n", __func__);
- return;
- }
-
- n = read(sock, buf, len);
+ n = read(sock, drv->event_buf, drv->event_buf_len);
if (n < 0) {
if (errno != EINTR && errno != EAGAIN)
- wpa_printf(MSG_ERROR, "%s read() failed: %s\n",
+ wpa_printf(MSG_ERROR, "%s read() failed: %s",
__func__, strerror(errno));
- os_free(buf);
return;
}
- rtm = (struct rt_msghdr *) buf;
+ rtm = (struct rt_msghdr *) drv->event_buf;
if (rtm->rtm_version != RTM_VERSION) {
wpa_printf(MSG_DEBUG, "Invalid routing message version=%d",
rtm->rtm_version);
- os_free(buf);
return;
}
ifan = (struct if_announcemsghdr *) rtm;
@@ -840,7 +790,6 @@ bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx)
}
break;
}
- os_free(buf);
}
static void
@@ -857,14 +806,23 @@ bsd_init(struct hostapd_data *hapd, struct wpa_init_params *params)
drv = os_zalloc(sizeof(struct bsd_driver_data));
if (drv == NULL) {
- printf("Could not allocate memory for bsd driver data\n");
+ wpa_printf(MSG_ERROR, "Could not allocate memory for bsd driver data");
+ return NULL;
+ }
+
+ drv->event_buf_len = rtbuf_len();
+
+ drv->event_buf = os_malloc(drv->event_buf_len);
+ if (drv->event_buf == NULL) {
+ wpa_printf(MSG_ERROR, "%s: os_malloc() failed", __func__);
goto bad;
}
drv->hapd = hapd;
drv->sock = socket(PF_INET, SOCK_DGRAM, 0);
if (drv->sock < 0) {
- perror("socket[PF_INET,SOCK_DGRAM]");
+ wpa_printf(MSG_ERROR, "socket[PF_INET,SOCK_DGRAM]: %s",
+ strerror(errno));
goto bad;
}
os_strlcpy(drv->ifname, params->ifname, sizeof(drv->ifname));
@@ -882,7 +840,8 @@ bsd_init(struct hostapd_data *hapd, struct wpa_init_params *params)
drv->route = socket(PF_ROUTE, SOCK_RAW, 0);
if (drv->route < 0) {
- perror("socket(PF_ROUTE,SOCK_RAW)");
+ wpa_printf(MSG_ERROR, "socket(PF_ROUTE,SOCK_RAW): %s",
+ strerror(errno));
goto bad;
}
eloop_register_read_sock(drv->route, bsd_wireless_event_receive, drv,
@@ -900,6 +859,7 @@ bad:
l2_packet_deinit(drv->sock_xmit);
if (drv->sock >= 0)
close(drv->sock);
+ os_free(drv->event_buf);
if (drv != NULL)
os_free(drv);
return NULL;
@@ -920,9 +880,37 @@ bsd_deinit(void *priv)
close(drv->sock);
if (drv->sock_xmit != NULL)
l2_packet_deinit(drv->sock_xmit);
+ os_free(drv->event_buf);
os_free(drv);
}
+
+static int
+bsd_commit(void *priv)
+{
+ return bsd_ctrl_iface(priv, 1);
+}
+
+
+static int
+bsd_set_sta_authorized(void *priv, const u8 *addr,
+ int total_flags, int flags_or, int flags_and)
+{
+ int authorized = -1;
+
+ /* For now, only support setting Authorized flag */
+ if (flags_or & WPA_STA_AUTHORIZED)
+ authorized = 1;
+ if (!(flags_and & WPA_STA_AUTHORIZED))
+ authorized = 0;
+
+ if (authorized < 0)
+ return 0;
+
+ return bsd_send_mlme_param(priv, authorized ?
+ IEEE80211_MLME_AUTHORIZE :
+ IEEE80211_MLME_UNAUTHORIZE, 0, addr);
+}
#else /* HOSTAPD */
static int
@@ -1100,9 +1088,9 @@ wpa_driver_bsd_associate(void *priv, struct wpa_driver_associate_params *params)
if (wpa_driver_bsd_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0)
return -1;
- privacy = !(params->pairwise_suite == CIPHER_NONE &&
- params->group_suite == CIPHER_NONE &&
- params->key_mgmt_suite == KEY_MGMT_NONE &&
+ privacy = !(params->pairwise_suite == WPA_CIPHER_NONE &&
+ params->group_suite == WPA_CIPHER_NONE &&
+ params->key_mgmt_suite == WPA_KEY_MGMT_NONE &&
params->wpa_ie_len == 0);
wpa_printf(MSG_DEBUG, "%s: set PRIVACY %u", __func__, privacy);
@@ -1198,7 +1186,6 @@ static void
wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
{
struct bsd_driver_data *drv = sock_ctx;
- char *buf;
struct if_announcemsghdr *ifan;
struct if_msghdr *ifm;
struct rt_msghdr *rtm;
@@ -1206,30 +1193,20 @@ wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
struct ieee80211_michael_event *mic;
struct ieee80211_leave_event *leave;
struct ieee80211_join_event *join;
- int n, len;
-
- len = rtbuf_len();
+ int n;
- buf = os_malloc(len);
- if (buf == NULL) {
- wpa_printf(MSG_ERROR, "%s os_malloc() failed\n", __func__);
- return;
- }
-
- n = read(sock, buf, len);
+ n = read(sock, drv->event_buf, drv->event_buf_len);
if (n < 0) {
if (errno != EINTR && errno != EAGAIN)
- wpa_printf(MSG_ERROR, "%s read() failed: %s\n",
+ wpa_printf(MSG_ERROR, "%s read() failed: %s",
__func__, strerror(errno));
- os_free(buf);
return;
}
- rtm = (struct rt_msghdr *) buf;
+ rtm = (struct rt_msghdr *) drv->event_buf;
if (rtm->rtm_version != RTM_VERSION) {
wpa_printf(MSG_DEBUG, "Invalid routing message version=%d",
rtm->rtm_version);
- os_free(buf);
return;
}
os_memset(&event, 0, sizeof(event));
@@ -1244,7 +1221,6 @@ wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
case IFAN_DEPARTURE:
event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
default:
- os_free(buf);
return;
}
wpa_printf(MSG_DEBUG, "RTM_IFANNOUNCE: Interface '%s' %s",
@@ -1317,7 +1293,6 @@ wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
}
break;
}
- os_free(buf);
}
static void
@@ -1368,7 +1343,12 @@ wpa_driver_bsd_add_scan_entry(struct wpa_scan_results *res,
*pos++ = 1;
*pos++ = sr->isr_erp;
+#if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+ os_memcpy(pos, (u8 *)(sr + 1) + sr->isr_ssid_len + sr->isr_meshid_len,
+ sr->isr_ie_len);
+#else
os_memcpy(pos, (u8 *)(sr + 1) + sr->isr_ssid_len, sr->isr_ie_len);
+#endif
pos += sr->isr_ie_len;
result->ie_len = pos - (u8 *)(result + 1);
@@ -1500,6 +1480,33 @@ static int wpa_driver_bsd_capa(struct bsd_driver_data *drv)
return 0;
}
+static enum ieee80211_opmode
+get80211opmode(struct bsd_driver_data *drv)
+{
+ struct ifmediareq ifmr;
+
+ (void) memset(&ifmr, 0, sizeof(ifmr));
+ (void) os_strlcpy(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;
+#ifdef IEEE80211_M_MBSS
+ if (ifmr.ifm_current & IFM_IEEE80211_MBSS)
+ return IEEE80211_M_MBSS;
+#endif /* IEEE80211_M_MBSS */
+ }
+ return IEEE80211_M_STA;
+}
+
static void *
wpa_driver_bsd_init(void *ctx, const char *ifname)
{
@@ -1510,6 +1517,15 @@ wpa_driver_bsd_init(void *ctx, const char *ifname)
drv = os_zalloc(sizeof(*drv));
if (drv == NULL)
return NULL;
+
+ drv->event_buf_len = rtbuf_len();
+
+ drv->event_buf = os_malloc(drv->event_buf_len);
+ if (drv->event_buf == NULL) {
+ wpa_printf(MSG_ERROR, "%s: os_malloc() failed", __func__);
+ goto fail1;
+ }
+
/*
* NB: We require the interface name be mappable to an index.
* This implies we do not support having wpa_supplicant
@@ -1564,6 +1580,7 @@ wpa_driver_bsd_init(void *ctx, const char *ifname)
fail:
close(drv->sock);
fail1:
+ os_free(drv->event_buf);
os_free(drv);
return NULL;
#undef GETPARAM
@@ -1589,6 +1606,7 @@ wpa_driver_bsd_deinit(void *priv)
l2_packet_deinit(drv->sock_xmit);
(void) close(drv->route); /* ioctl socket */
(void) close(drv->sock); /* event socket */
+ os_free(drv->event_buf);
os_free(drv);
}
OpenPOWER on IntegriCloud