diff options
author | rpaulo <rpaulo@FreeBSD.org> | 2015-04-21 01:45:11 +0000 |
---|---|---|
committer | rpaulo <rpaulo@FreeBSD.org> | 2015-04-21 01:45:11 +0000 |
commit | 842f4520d0888b29092df5d0d02c98cf458d22f7 (patch) | |
tree | 2cc3a30a65916dde45972adbf0d20263dbd38514 /contrib/wpa/src/drivers/driver_bsd.c | |
parent | 2b5cce437990f63ca2ad7e2ec6f65e2d91d98f43 (diff) | |
parent | 30dc5ae44f65d272ea1e32635149befdbf9833cf (diff) | |
download | FreeBSD-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.c | 238 |
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); } |