Adapt for wpa_supplicant / hostapd 0.7.3.
This commit is contained in:
parent
e28a4053b1
commit
5d6ccd39d5
|
@ -3,17 +3,31 @@
|
||||||
.include "${.CURDIR}/../Makefile.inc"
|
.include "${.CURDIR}/../Makefile.inc"
|
||||||
|
|
||||||
.PATH.c:${HOSTAPD_DISTDIR} \
|
.PATH.c:${HOSTAPD_DISTDIR} \
|
||||||
|
${WPA_DISTDIR}/src/ap \
|
||||||
${WPA_DISTDIR}/src/eap_server \
|
${WPA_DISTDIR}/src/eap_server \
|
||||||
|
${WPA_DISTDIR}/src/eap_common \
|
||||||
|
${WPA_DISTDIR}/src/eapol_auth \
|
||||||
|
${WPA_DISTDIR}/src/drivers \
|
||||||
${WPA_DISTDIR}/src/radius \
|
${WPA_DISTDIR}/src/radius \
|
||||||
|
${WPA_DISTDIR}
|
||||||
|
|
||||||
PROG= hostapd
|
PROG= hostapd
|
||||||
SRCS= accounting.c aes.c aes_wrap.c ap_list.c beacon.c common.c \
|
SRCS= accounting.c aes-wrap.c ap_config.c \
|
||||||
config.c ctrl_iface.c drivers.c eapol_sm.c eap.c eap_common.c \
|
ap_drv_ops.c ap_mlme.c authsrv.c \
|
||||||
eap_identity.c eap_methods.c eloop.c hostapd.c \
|
chap.c common.c config_file.c ctrl_iface.c crypto_openssl.c \
|
||||||
hw_features.c ieee802_11.c ieee802_11_common.c ieee802_11_auth.c \
|
ctrl_iface_ap.c drivers.c drv_callbacks.c dump_state.c \
|
||||||
ieee802_1x.c ip_addr.c md5.c mlme.c pmksa_cache.c radius.c \
|
eap_common.c eap_peap_common.c eap_register.c eap_server.c \
|
||||||
radius_client.c rc4.c sha1.c sta_info.c vlan_init.c wme.c \
|
eap_server_gtc.c eap_server_identity.c eap_server_md5.c \
|
||||||
wpa.c wpa_auth_ie.c wpa_common.c wpa_debug.c wpabuf.c
|
eap_server_methods.c eap_server_mschapv2.c eap_server_peap.c \
|
||||||
|
eap_server_tls.c eap_server_tls_common.c eap_server_ttls.c \
|
||||||
|
eapol_auth_dump.c eapol_auth_sm.c eloop.c hostapd.c ieee802_11_auth.c \
|
||||||
|
ieee802_11_common.c ieee802_11_ht.c ieee802_1x.c ip_addr.c \
|
||||||
|
md5.c main.c ms_funcs.c peerkey_auth.c pmksa_cache_auth.c \
|
||||||
|
preauth_auth.c radius.c radius_client.c sta_info.c \
|
||||||
|
sha1-pbkdf2.c sha1-tlsprf.c sha1-tprf.c sha1.c \
|
||||||
|
tkip_countermeasures.c utils.c \
|
||||||
|
vlan_init.c wpa_auth.c wpa_auth_glue.c wpa_auth_ie.c wpa_common.c \
|
||||||
|
wpa_debug.c wpabuf.c
|
||||||
SRCS+= l2_packet_freebsd.c driver_freebsd.c os_unix.c
|
SRCS+= l2_packet_freebsd.c driver_freebsd.c os_unix.c
|
||||||
|
|
||||||
MAN= hostapd.8 hostapd.conf.5
|
MAN= hostapd.8 hostapd.conf.5
|
||||||
|
@ -24,16 +38,16 @@ FILESDIR= ${SHAREDIR}/examples/hostapd
|
||||||
FILES= hostapd.conf hostapd.eap_user hostapd.wpa_psk
|
FILES= hostapd.conf hostapd.eap_user hostapd.wpa_psk
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
CFLAGS+= -I${HOSTAPD_DISTDIR}
|
CFLAGS+= -I${HOSTAPD_DISTDIR} -I${WPA_DISTDIR}/src/drivers
|
||||||
|
|
||||||
CFLAGS+= -DCONFIG_DRIVER_BSD
|
CFLAGS+= -DCONFIG_DRIVER_BSD -DHOSTAPD
|
||||||
CFLAGS+= -DCONFIG_DRIVER_RADIUS_ACL
|
CFLAGS+= -DCONFIG_DRIVER_RADIUS_ACL
|
||||||
.if ${MK_INET6} != "no"
|
.if ${MK_INET6} != "no"
|
||||||
CFLAGS+= -DCONFIG_IPV6
|
CFLAGS+= -DCONFIG_IPV6
|
||||||
.endif
|
.endif
|
||||||
CFLAGS+= -g
|
#CFLAGS+= -g
|
||||||
DPADD+= ${LIBPCAP}
|
DPADD+= ${LIBPCAP} ${LIBSSL}
|
||||||
LDADD+= -lpcap
|
LDADD+= -lpcap -lssl
|
||||||
|
|
||||||
# User customizations for wpa_supplicant/hostapd build environment
|
# User customizations for wpa_supplicant/hostapd build environment
|
||||||
CFLAGS+=${HOSTAPD_CFLAGS}
|
CFLAGS+=${HOSTAPD_CFLAGS}
|
||||||
|
|
|
@ -14,12 +14,13 @@
|
||||||
*
|
*
|
||||||
* $FreeBSD$
|
* $FreeBSD$
|
||||||
*/
|
*/
|
||||||
#include <stdlib.h>
|
#include "includes.h"
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <errno.h>
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "driver.h"
|
||||||
|
#include "eloop.h"
|
||||||
|
#include "common/ieee802_11_defs.h"
|
||||||
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
|
@ -32,34 +33,29 @@
|
||||||
#undef WPA_OUI_TYPE
|
#undef WPA_OUI_TYPE
|
||||||
#undef WME_OUI_TYPE
|
#undef WME_OUI_TYPE
|
||||||
|
|
||||||
#include "hostapd.h"
|
|
||||||
#include "driver.h"
|
|
||||||
#include "ieee802_1x.h"
|
|
||||||
#include "ieee802_11_auth.h"
|
|
||||||
#include "eloop.h"
|
|
||||||
#include "sta_info.h"
|
|
||||||
#include "l2_packet/l2_packet.h"
|
#include "l2_packet/l2_packet.h"
|
||||||
|
|
||||||
#include "eapol_sm.h"
|
|
||||||
#include "wpa.h"
|
|
||||||
#include "radius/radius.h"
|
|
||||||
#include "ieee802_11.h"
|
|
||||||
#include "common.h"
|
|
||||||
#include "hostap_common.h"
|
|
||||||
|
|
||||||
struct bsd_driver_data {
|
struct bsd_driver_data {
|
||||||
struct hostapd_data *hapd; /* back pointer */
|
struct hostapd_data *hapd; /* back pointer */
|
||||||
|
|
||||||
char iface[IFNAMSIZ + 1];
|
int ioctl_sock; /* open socket for 802.11 ioctls */
|
||||||
unsigned int ifindex; /* interface index */
|
int wext_sock;
|
||||||
struct l2_packet_data *sock_xmit; /* raw packet xmit socket */
|
struct l2_packet_data *sock_xmit;/* raw packet xmit socket */
|
||||||
int ioctl_sock; /* socket for ioctl() use */
|
int route; /* routing socket for events */
|
||||||
int wext_sock; /* socket for wireless events */
|
char iface[IFNAMSIZ+1]; /* interface name */
|
||||||
|
unsigned int ifindex; /* interface index */
|
||||||
|
void *ctx;
|
||||||
|
struct wpa_driver_capa capa; /* driver capability */
|
||||||
|
int is_ap; /* Access point mode */
|
||||||
|
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 */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct wpa_driver_ops bsd_driver_ops;
|
static const struct wpa_driver_ops bsd_driver_ops;
|
||||||
|
|
||||||
static int bsd_sta_deauth(void *priv, const u8 *addr, int reason_code);
|
static int bsd_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
|
||||||
|
int reason_code);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
set80211var(struct bsd_driver_data *drv, int op, const void *arg, int arg_len)
|
set80211var(struct bsd_driver_data *drv, int op, const void *arg, int arg_len)
|
||||||
|
@ -171,44 +167,37 @@ bsd_commit(void *priv)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bsd_set_ieee8021x(const char *ifname, void *priv, int enabled)
|
bsd_set_ieee8021x(void *priv, struct wpa_bss_params *params)
|
||||||
{
|
{
|
||||||
struct bsd_driver_data *drv = priv;
|
wpa_printf(MSG_DEBUG, "%s: enabled=%d\n", __func__, params->enabled);
|
||||||
struct hostapd_data *hapd = drv->hapd;
|
|
||||||
struct hostapd_bss_config *conf = hapd->conf;
|
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "%s: enabled=%d\n", __func__, enabled);
|
if (!params->enabled) {
|
||||||
|
|
||||||
if (!enabled) {
|
|
||||||
/* XXX restore state */
|
/* XXX restore state */
|
||||||
return set80211param(priv, IEEE80211_IOC_AUTHMODE,
|
return set80211param(priv, IEEE80211_IOC_AUTHMODE,
|
||||||
IEEE80211_AUTH_AUTO);
|
IEEE80211_AUTH_AUTO);
|
||||||
}
|
}
|
||||||
if (!conf->wpa && !conf->ieee802_1x) {
|
if (!params->wpa && !params->ieee802_1x) {
|
||||||
hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER,
|
wpa_printf(MSG_ERROR, "%s: No 802.1X or WPA enabled",
|
||||||
HOSTAPD_LEVEL_WARNING, "No 802.1X or WPA enabled!");
|
__func__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (conf->wpa && set80211param(drv, IEEE80211_IOC_WPA, conf->wpa)) {
|
if (params->wpa && set80211param(priv,IEEE80211_IOC_WPA, params->wpa)) {
|
||||||
hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER,
|
wpa_printf(MSG_ERROR, "%s: Failed to configure WPA state",
|
||||||
HOSTAPD_LEVEL_WARNING, "Error configuring WPA state!");
|
__func__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (set80211param(priv, IEEE80211_IOC_AUTHMODE,
|
if (set80211param(priv, IEEE80211_IOC_AUTHMODE,
|
||||||
(conf->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) {
|
(params->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) {
|
||||||
hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER,
|
wpa_printf(MSG_ERROR, "%s: Failed to enable WPA/802.1X",
|
||||||
HOSTAPD_LEVEL_WARNING, "Error enabling WPA/802.1X!");
|
__func__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bsd_set_privacy(const char *ifname, void *priv, int enabled)
|
bsd_set_privacy(void *priv, int enabled)
|
||||||
{
|
{
|
||||||
struct bsd_driver_data *drv = priv;
|
|
||||||
struct hostapd_data *hapd = drv->hapd;
|
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "%s: enabled=%d\n", __func__, enabled);
|
wpa_printf(MSG_DEBUG, "%s: enabled=%d\n", __func__, enabled);
|
||||||
|
|
||||||
return set80211param(priv, IEEE80211_IOC_PRIVACY, enabled);
|
return set80211param(priv, IEEE80211_IOC_PRIVACY, enabled);
|
||||||
|
@ -238,9 +227,9 @@ bsd_sta_set_flags(void *priv, const u8 *addr, int total_flags,
|
||||||
int flags_or, int flags_and)
|
int flags_or, int flags_and)
|
||||||
{
|
{
|
||||||
/* For now, only support setting Authorized flag */
|
/* For now, only support setting Authorized flag */
|
||||||
if (flags_or & WLAN_STA_AUTHORIZED)
|
if (flags_or & WPA_STA_AUTHORIZED)
|
||||||
return bsd_set_sta_authorized(priv, addr, 1);
|
return bsd_set_sta_authorized(priv, addr, 1);
|
||||||
if (!(flags_and & WLAN_STA_AUTHORIZED))
|
if (!(flags_and & WPA_STA_AUTHORIZED))
|
||||||
return bsd_set_sta_authorized(priv, addr, 0);
|
return bsd_set_sta_authorized(priv, addr, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -267,53 +256,64 @@ bsd_del_key(void *priv, const unsigned char *addr, int key_idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bsd_set_key(const char *ifname, void *priv, const char *alg,
|
bsd_set_key(const char *ifname, void *priv, enum wpa_alg alg,
|
||||||
const u8 *addr, int key_idx,
|
const unsigned char *addr, int key_idx, int set_tx, const u8 *seq,
|
||||||
const u8 *key, size_t key_len, int txkey)
|
size_t seq_len, const u8 *key, size_t key_len)
|
||||||
{
|
{
|
||||||
struct bsd_driver_data *drv = priv;
|
|
||||||
struct hostapd_data *hapd = drv->hapd;
|
|
||||||
struct ieee80211req_key wk;
|
struct ieee80211req_key wk;
|
||||||
u_int8_t cipher;
|
|
||||||
|
|
||||||
if (strcmp(alg, "none") == 0)
|
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,
|
||||||
|
set_tx, seq_len, key_len);
|
||||||
|
|
||||||
|
if (alg == WPA_ALG_NONE) {
|
||||||
return bsd_del_key(priv, addr, key_idx);
|
return bsd_del_key(priv, addr, key_idx);
|
||||||
|
}
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "%s: alg=%s addr=%s key_idx=%d\n",
|
os_memset(&wk, 0, sizeof(wk));
|
||||||
__func__, alg, ether_sprintf(addr), key_idx);
|
switch (alg) {
|
||||||
|
case WPA_ALG_WEP:
|
||||||
if (strcmp(alg, "WEP") == 0)
|
wk.ik_type = IEEE80211_CIPHER_WEP;
|
||||||
cipher = IEEE80211_CIPHER_WEP;
|
break;
|
||||||
else if (strcmp(alg, "TKIP") == 0)
|
case WPA_ALG_TKIP:
|
||||||
cipher = IEEE80211_CIPHER_TKIP;
|
wk.ik_type = IEEE80211_CIPHER_TKIP;
|
||||||
else if (strcmp(alg, "CCMP") == 0)
|
break;
|
||||||
cipher = IEEE80211_CIPHER_AES_CCM;
|
case WPA_ALG_CCMP:
|
||||||
else {
|
wk.ik_type = IEEE80211_CIPHER_AES_CCM;
|
||||||
printf("%s: unknown/unsupported algorithm %s\n",
|
break;
|
||||||
__func__, alg);
|
default:
|
||||||
|
wpa_printf(MSG_ERROR, "%s: unknown alg=%d", __func__, alg);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key_len > sizeof(wk.ik_keydata)) {
|
wk.ik_flags = IEEE80211_KEY_RECV;
|
||||||
printf("%s: key length %d too big\n", __func__, key_len);
|
if (set_tx)
|
||||||
return -3;
|
wk.ik_flags |= IEEE80211_KEY_XMIT;
|
||||||
}
|
|
||||||
|
|
||||||
memset(&wk, 0, sizeof(wk));
|
|
||||||
wk.ik_type = cipher;
|
|
||||||
if (addr == NULL) {
|
if (addr == NULL) {
|
||||||
memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
|
os_memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
|
||||||
wk.ik_keyix = key_idx;
|
wk.ik_keyix = key_idx;
|
||||||
wk.ik_flags = IEEE80211_KEY_XMIT
|
|
||||||
| IEEE80211_KEY_GROUP
|
|
||||||
| IEEE80211_KEY_DEFAULT;
|
|
||||||
} else {
|
} else {
|
||||||
memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
|
os_memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
|
||||||
wk.ik_keyix = IEEE80211_KEYIX_NONE;
|
/*
|
||||||
wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT;
|
* Deduce whether group/global or unicast key by checking
|
||||||
|
* the address (yech). Note also that we can only mark global
|
||||||
|
* keys default; doing this for a unicast key is an error.
|
||||||
|
*/
|
||||||
|
if (os_memcmp(addr, "\xff\xff\xff\xff\xff\xff",
|
||||||
|
IEEE80211_ADDR_LEN) == 0) {
|
||||||
|
wk.ik_flags |= IEEE80211_KEY_GROUP;
|
||||||
|
wk.ik_keyix = key_idx;
|
||||||
|
} else {
|
||||||
|
wk.ik_keyix = key_idx == 0 ? IEEE80211_KEYIX_NONE :
|
||||||
|
key_idx;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (wk.ik_keyix != IEEE80211_KEYIX_NONE && set_tx)
|
||||||
|
wk.ik_flags |= IEEE80211_KEY_DEFAULT;
|
||||||
wk.ik_keylen = key_len;
|
wk.ik_keylen = key_len;
|
||||||
memcpy(wk.ik_keydata, key, key_len);
|
os_memcpy(&wk.ik_keyrsc, seq, seq_len);
|
||||||
|
os_memcpy(wk.ik_keydata, key, key_len);
|
||||||
|
|
||||||
return set80211var(priv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk));
|
return set80211var(priv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk));
|
||||||
}
|
}
|
||||||
|
@ -355,7 +355,7 @@ bsd_flush(void *priv)
|
||||||
u8 allsta[IEEE80211_ADDR_LEN];
|
u8 allsta[IEEE80211_ADDR_LEN];
|
||||||
|
|
||||||
memset(allsta, 0xff, IEEE80211_ADDR_LEN);
|
memset(allsta, 0xff, IEEE80211_ADDR_LEN);
|
||||||
return bsd_sta_deauth(priv, allsta, IEEE80211_REASON_AUTH_LEAVE);
|
return bsd_sta_deauth(priv, NULL, allsta, IEEE80211_REASON_AUTH_LEAVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -393,7 +393,7 @@ bsd_sta_clear_stats(void *priv, const u8 *addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bsd_set_opt_ie(const char *ifname, void *priv, const u8 *ie, size_t ie_len)
|
bsd_set_opt_ie(void *priv, const u8 *ie, size_t ie_len)
|
||||||
{
|
{
|
||||||
struct bsd_driver_data *drv = priv;
|
struct bsd_driver_data *drv = priv;
|
||||||
struct hostapd_data *hapd = drv->hapd;
|
struct hostapd_data *hapd = drv->hapd;
|
||||||
|
@ -416,7 +416,7 @@ bsd_set_opt_ie(const char *ifname, void *priv, const u8 *ie, size_t ie_len)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bsd_sta_deauth(void *priv, const u8 *addr, int reason_code)
|
bsd_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, int reason_code)
|
||||||
{
|
{
|
||||||
struct bsd_driver_data *drv = priv;
|
struct bsd_driver_data *drv = priv;
|
||||||
struct hostapd_data *hapd = drv->hapd;
|
struct hostapd_data *hapd = drv->hapd;
|
||||||
|
@ -432,7 +432,7 @@ bsd_sta_deauth(void *priv, const u8 *addr, int reason_code)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bsd_sta_disassoc(void *priv, const u8 *addr, int reason_code)
|
bsd_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr, int reason_code)
|
||||||
{
|
{
|
||||||
struct bsd_driver_data *drv = priv;
|
struct bsd_driver_data *drv = priv;
|
||||||
struct hostapd_data *hapd = drv->hapd;
|
struct hostapd_data *hapd = drv->hapd;
|
||||||
|
@ -446,85 +446,32 @@ bsd_sta_disassoc(void *priv, const u8 *addr, int reason_code)
|
||||||
return set80211var(priv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme));
|
return set80211var(priv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
bsd_del_sta(struct bsd_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN])
|
bsd_new_sta(void *priv, void *ctx, u8 addr[IEEE80211_ADDR_LEN])
|
||||||
{
|
{
|
||||||
struct hostapd_data *hapd = drv->hapd;
|
|
||||||
struct hostapd_bss_config *conf = hapd->conf;
|
|
||||||
struct sta_info *sta;
|
|
||||||
|
|
||||||
hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
|
|
||||||
HOSTAPD_LEVEL_INFO, "deassociated");
|
|
||||||
|
|
||||||
sta = ap_get_sta(hapd, addr);
|
|
||||||
if (sta != NULL) {
|
|
||||||
sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
|
|
||||||
if (conf->wpa)
|
|
||||||
wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
|
|
||||||
sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
|
|
||||||
ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
|
|
||||||
ap_free_sta(hapd, sta);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
bsd_new_sta(struct bsd_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN])
|
|
||||||
{
|
|
||||||
struct hostapd_data *hapd = drv->hapd;
|
|
||||||
struct hostapd_bss_config *conf = hapd->conf;
|
|
||||||
struct sta_info *sta;
|
|
||||||
struct ieee80211req_wpaie ie;
|
struct ieee80211req_wpaie ie;
|
||||||
int new_assoc, ielen, res;
|
int ielen = 0;
|
||||||
|
u8 *iebuf = NULL;
|
||||||
|
|
||||||
hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
|
|
||||||
HOSTAPD_LEVEL_INFO, "associated");
|
|
||||||
|
|
||||||
sta = ap_sta_add(hapd, addr);
|
|
||||||
if (sta == NULL)
|
|
||||||
return -1;
|
|
||||||
/*
|
/*
|
||||||
* Fetch and validate any negotiated WPA/RSN parameters.
|
* Fetch and validate any negotiated WPA/RSN parameters.
|
||||||
*/
|
*/
|
||||||
if (conf->wpa) {
|
memset(&ie, 0, sizeof(ie));
|
||||||
memset(&ie, 0, sizeof(ie));
|
memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN);
|
||||||
memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN);
|
if (get80211var(priv, IEEE80211_IOC_WPAIE, &ie, sizeof(ie)) < 0) {
|
||||||
if (get80211var(drv, IEEE80211_IOC_WPAIE, &ie, sizeof(ie)) < 0) {
|
printf("Failed to get WPA/RSN information element.\n");
|
||||||
printf("Failed to get WPA/RSN information element.\n");
|
goto no_ie;
|
||||||
return -1; /* XXX not right */
|
|
||||||
}
|
|
||||||
if (ie.wpa_ie[1] == 0) {
|
|
||||||
printf("No WPA/RSN information element for station!\n");
|
|
||||||
return -1; /* XXX not right */
|
|
||||||
}
|
|
||||||
if (sta->wpa_sm == NULL)
|
|
||||||
sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
|
|
||||||
sta->addr);
|
|
||||||
if (sta->wpa_sm == NULL) {
|
|
||||||
printf("Failed to initialize WPA state machine\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
ielen = 2 + ie.wpa_ie[1];
|
|
||||||
res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
|
|
||||||
ie.wpa_ie, ielen, NULL, 0);
|
|
||||||
if (res != WPA_IE_OK) {
|
|
||||||
printf("WPA/RSN information element rejected? "
|
|
||||||
"(res %u)\n", res);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
iebuf = ie.wpa_ie;
|
||||||
|
ielen = ie.wpa_ie[1];
|
||||||
|
if (ielen == 0)
|
||||||
|
iebuf = NULL;
|
||||||
|
else
|
||||||
|
ielen += 2;
|
||||||
|
|
||||||
/*
|
no_ie:
|
||||||
* Now that the internal station state is setup
|
drv_event_assoc(ctx, addr, iebuf, ielen);
|
||||||
* kick the authenticator into action.
|
|
||||||
*/
|
|
||||||
new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;
|
|
||||||
sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
|
|
||||||
wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
|
|
||||||
hostapd_new_assoc_sta(hapd, sta, !new_assoc);
|
|
||||||
ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <net/route.h>
|
#include <net/route.h>
|
||||||
|
@ -545,6 +492,7 @@ bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx)
|
||||||
struct ieee80211_auth_event *auth;
|
struct ieee80211_auth_event *auth;
|
||||||
#endif
|
#endif
|
||||||
int n;
|
int n;
|
||||||
|
union wpa_event_data data;
|
||||||
|
|
||||||
n = read(sock, buf, sizeof(buf));
|
n = read(sock, buf, sizeof(buf));
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
|
@ -576,14 +524,14 @@ bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx)
|
||||||
break;
|
break;
|
||||||
case RTM_IEEE80211_LEAVE:
|
case RTM_IEEE80211_LEAVE:
|
||||||
leave = (struct ieee80211_leave_event *) &ifan[1];
|
leave = (struct ieee80211_leave_event *) &ifan[1];
|
||||||
bsd_del_sta(drv, leave->iev_addr);
|
drv_event_disassoc(drv->hapd, leave->iev_addr);
|
||||||
break;
|
break;
|
||||||
case RTM_IEEE80211_JOIN:
|
case RTM_IEEE80211_JOIN:
|
||||||
#ifdef RTM_IEEE80211_REJOIN
|
#ifdef RTM_IEEE80211_REJOIN
|
||||||
case RTM_IEEE80211_REJOIN:
|
case RTM_IEEE80211_REJOIN:
|
||||||
#endif
|
#endif
|
||||||
join = (struct ieee80211_join_event *) &ifan[1];
|
join = (struct ieee80211_join_event *) &ifan[1];
|
||||||
bsd_new_sta(drv, join->iev_addr);
|
bsd_new_sta(drv, drv->hapd, join->iev_addr);
|
||||||
break;
|
break;
|
||||||
case RTM_IEEE80211_REPLAY:
|
case RTM_IEEE80211_REPLAY:
|
||||||
/* ignore */
|
/* ignore */
|
||||||
|
@ -594,9 +542,13 @@ bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx)
|
||||||
"Michael MIC failure wireless event: "
|
"Michael MIC failure wireless event: "
|
||||||
"keyix=%u src_addr=" MACSTR, mic->iev_keyix,
|
"keyix=%u src_addr=" MACSTR, mic->iev_keyix,
|
||||||
MAC2STR(mic->iev_src));
|
MAC2STR(mic->iev_src));
|
||||||
ieee80211_michael_mic_failure(hapd, mic->iev_src, 1);
|
os_memset(&data, 0, sizeof(data));
|
||||||
|
data.michael_mic_failure.unicast = 1;
|
||||||
|
data.michael_mic_failure.src = mic->iev_src;
|
||||||
|
wpa_supplicant_event(drv->hapd,
|
||||||
|
EVENT_MICHAEL_MIC_FAILURE, &data);
|
||||||
break;
|
break;
|
||||||
#ifdef CONFIG_DRIVER_RADIUS_ACL
|
#ifdef CONFIG_DRIVER_RADIUS_ACL_NOT_YET
|
||||||
case RTM_IEEE80211_AUTH:
|
case RTM_IEEE80211_AUTH:
|
||||||
auth = (struct ieee80211_auth_event *) &ifan[1];
|
auth = (struct ieee80211_auth_event *) &ifan[1];
|
||||||
wpa_printf(MSG_DEBUG, "802.11 AUTH, STA = " MACSTR,
|
wpa_printf(MSG_DEBUG, "802.11 AUTH, STA = " MACSTR,
|
||||||
|
@ -627,42 +579,10 @@ bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
bsd_wireless_event_init(void *priv)
|
|
||||||
{
|
|
||||||
struct bsd_driver_data *drv = priv;
|
|
||||||
int s;
|
|
||||||
|
|
||||||
drv->wext_sock = -1;
|
|
||||||
|
|
||||||
s = socket(PF_ROUTE, SOCK_RAW, 0);
|
|
||||||
if (s < 0) {
|
|
||||||
perror("socket(PF_ROUTE,SOCK_RAW)");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
eloop_register_read_sock(s, bsd_wireless_event_receive, drv, NULL);
|
|
||||||
drv->wext_sock = s;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
bsd_wireless_event_deinit(void *priv)
|
|
||||||
{
|
|
||||||
struct bsd_driver_data *drv = priv;
|
|
||||||
|
|
||||||
if (drv != NULL) {
|
|
||||||
if (drv->wext_sock < 0)
|
|
||||||
return;
|
|
||||||
eloop_unregister_read_sock(drv->wext_sock);
|
|
||||||
close(drv->wext_sock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bsd_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len,
|
bsd_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len,
|
||||||
int encrypt, const u8 *own_addr)
|
int encrypt, const u8 *own_addr)
|
||||||
|
|
||||||
{
|
{
|
||||||
struct bsd_driver_data *drv = priv;
|
struct bsd_driver_data *drv = priv;
|
||||||
struct hostapd_data *hapd = drv->hapd;
|
struct hostapd_data *hapd = drv->hapd;
|
||||||
|
@ -706,25 +626,14 @@ static void
|
||||||
handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)
|
handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)
|
||||||
{
|
{
|
||||||
struct bsd_driver_data *drv = ctx;
|
struct bsd_driver_data *drv = ctx;
|
||||||
struct hostapd_data *hapd = drv->hapd;
|
drv_event_eapol_rx(drv->hapd, src_addr, buf, len);
|
||||||
struct sta_info *sta;
|
|
||||||
|
|
||||||
sta = ap_get_sta(hapd, src_addr);
|
|
||||||
if (!sta || !(sta->flags & WLAN_STA_ASSOC)) {
|
|
||||||
printf("Data frame from not associated STA %s\n",
|
|
||||||
ether_sprintf(src_addr));
|
|
||||||
/* XXX cannot happen */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ieee802_1x_receive(hapd, src_addr, buf + sizeof(struct l2_ethhdr),
|
|
||||||
len - sizeof(struct l2_ethhdr));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bsd_get_ssid(const char *ifname, void *priv, u8 *buf, int len)
|
bsd_get_ssid(void *priv, u8 *buf, int len)
|
||||||
{
|
{
|
||||||
struct bsd_driver_data *drv = priv;
|
struct bsd_driver_data *drv = priv;
|
||||||
struct hostapd_data *hapd = drv->hapd;
|
|
||||||
int ssid_len = get80211var(priv, IEEE80211_IOC_SSID, buf, len);
|
int ssid_len = get80211var(priv, IEEE80211_IOC_SSID, buf, len);
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "%s: ssid=\"%.*s\"\n", __func__, ssid_len, buf);
|
wpa_printf(MSG_DEBUG, "%s: ssid=\"%.*s\"\n", __func__, ssid_len, buf);
|
||||||
|
@ -733,7 +642,7 @@ bsd_get_ssid(const char *ifname, void *priv, u8 *buf, int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bsd_set_ssid(const char *ifname, void *priv, const u8 *buf, int len)
|
bsd_set_ssid(void *priv, const u8 *buf, int len)
|
||||||
{
|
{
|
||||||
struct bsd_driver_data *drv = priv;
|
struct bsd_driver_data *drv = priv;
|
||||||
struct hostapd_data *hapd = drv->hapd;
|
struct hostapd_data *hapd = drv->hapd;
|
||||||
|
@ -752,7 +661,7 @@ bsd_set_countermeasures(void *priv, int enabled)
|
||||||
return set80211param(drv, IEEE80211_IOC_COUNTERMEASURES, enabled);
|
return set80211param(drv, IEEE80211_IOC_COUNTERMEASURES, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_DRIVER_RADIUS_ACL
|
#ifdef CONFIG_DRIVER_RADIUS_ACL_NOT_YET
|
||||||
static int
|
static int
|
||||||
bsd_set_radius_acl_auth(void *priv, const u8 *mac, int accepted,
|
bsd_set_radius_acl_auth(void *priv, const u8 *mac, int accepted,
|
||||||
u32 session_timeout)
|
u32 session_timeout)
|
||||||
|
@ -814,24 +723,23 @@ bsd_set_radius_acl_expire(void *priv, const u8 *mac)
|
||||||
#endif /* CONFIG_DRIVER_RADIUS_ACL */
|
#endif /* CONFIG_DRIVER_RADIUS_ACL */
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
bsd_init(struct hostapd_data *hapd)
|
bsd_init(struct hostapd_data *hapd, struct wpa_init_params *params)
|
||||||
{
|
{
|
||||||
struct bsd_driver_data *drv;
|
struct bsd_driver_data *drv;
|
||||||
|
|
||||||
drv = malloc(sizeof(struct bsd_driver_data));
|
drv = os_zalloc(sizeof(struct bsd_driver_data));
|
||||||
if (drv == NULL) {
|
if (drv == NULL) {
|
||||||
printf("Could not allocate memory for bsd driver data\n");
|
printf("Could not allocate memory for bsd driver data\n");
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(drv, 0, sizeof(*drv));
|
|
||||||
drv->hapd = hapd;
|
drv->hapd = hapd;
|
||||||
drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
|
drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
|
||||||
if (drv->ioctl_sock < 0) {
|
if (drv->ioctl_sock < 0) {
|
||||||
perror("socket[PF_INET,SOCK_DGRAM]");
|
perror("socket[PF_INET,SOCK_DGRAM]");
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
memcpy(drv->iface, hapd->conf->iface, sizeof(drv->iface));
|
memcpy(drv->iface, params->ifname, sizeof(drv->iface));
|
||||||
/*
|
/*
|
||||||
* NB: We require the interface name be mappable to an index.
|
* NB: We require the interface name be mappable to an index.
|
||||||
* This implies we do not support having wpa_supplicant
|
* This implies we do not support having wpa_supplicant
|
||||||
|
@ -849,10 +757,20 @@ bsd_init(struct hostapd_data *hapd)
|
||||||
handle_read, drv, 1);
|
handle_read, drv, 1);
|
||||||
if (drv->sock_xmit == NULL)
|
if (drv->sock_xmit == NULL)
|
||||||
goto bad;
|
goto bad;
|
||||||
if (l2_packet_get_own_addr(drv->sock_xmit, hapd->own_addr))
|
if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr))
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
bsd_set_iface_flags(drv, -IFF_UP); /* mark down during setup */
|
/* mark down during setup */
|
||||||
|
if (bsd_set_iface_flags(drv, -IFF_UP) < 0)
|
||||||
|
goto bad;
|
||||||
|
|
||||||
|
drv->route = socket(PF_ROUTE, SOCK_RAW, 0);
|
||||||
|
if (drv->route < 0) {
|
||||||
|
perror("socket(PF_ROUTE,SOCK_RAW)");
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
eloop_register_read_sock(drv->route, bsd_wireless_event_receive, drv,
|
||||||
|
NULL);
|
||||||
|
|
||||||
return drv;
|
return drv;
|
||||||
bad:
|
bad:
|
||||||
|
@ -872,6 +790,10 @@ bsd_deinit(void *priv)
|
||||||
{
|
{
|
||||||
struct bsd_driver_data *drv = priv;
|
struct bsd_driver_data *drv = priv;
|
||||||
|
|
||||||
|
if (drv->route >= 0) {
|
||||||
|
eloop_unregister_read_sock(drv->route);
|
||||||
|
close(drv->route);
|
||||||
|
}
|
||||||
(void) bsd_set_iface_flags(drv, -IFF_UP);
|
(void) bsd_set_iface_flags(drv, -IFF_UP);
|
||||||
if (drv->ioctl_sock >= 0)
|
if (drv->ioctl_sock >= 0)
|
||||||
close(drv->ioctl_sock);
|
close(drv->ioctl_sock);
|
||||||
|
@ -882,27 +804,25 @@ bsd_deinit(void *priv)
|
||||||
|
|
||||||
const struct wpa_driver_ops wpa_driver_bsd_ops = {
|
const struct wpa_driver_ops wpa_driver_bsd_ops = {
|
||||||
.name = "bsd",
|
.name = "bsd",
|
||||||
.init = bsd_init,
|
.hapd_init = bsd_init,
|
||||||
.deinit = bsd_deinit,
|
.hapd_deinit = bsd_deinit,
|
||||||
.set_ieee8021x = bsd_set_ieee8021x,
|
.set_ieee8021x = bsd_set_ieee8021x,
|
||||||
.set_privacy = bsd_set_privacy,
|
.set_privacy = bsd_set_privacy,
|
||||||
.set_encryption = bsd_set_key,
|
.set_key = bsd_set_key,
|
||||||
.get_seqnum = bsd_get_seqnum,
|
.get_seqnum = bsd_get_seqnum,
|
||||||
.flush = bsd_flush,
|
.flush = bsd_flush,
|
||||||
.set_generic_elem = bsd_set_opt_ie,
|
.set_generic_elem = bsd_set_opt_ie,
|
||||||
.wireless_event_init = bsd_wireless_event_init,
|
|
||||||
.wireless_event_deinit = bsd_wireless_event_deinit,
|
|
||||||
.sta_set_flags = bsd_sta_set_flags,
|
.sta_set_flags = bsd_sta_set_flags,
|
||||||
.read_sta_data = bsd_read_sta_driver_data,
|
.read_sta_data = bsd_read_sta_driver_data,
|
||||||
.send_eapol = bsd_send_eapol,
|
.hapd_send_eapol = bsd_send_eapol,
|
||||||
.sta_disassoc = bsd_sta_disassoc,
|
.sta_disassoc = bsd_sta_disassoc,
|
||||||
.sta_deauth = bsd_sta_deauth,
|
.sta_deauth = bsd_sta_deauth,
|
||||||
.set_ssid = bsd_set_ssid,
|
.hapd_set_ssid = bsd_set_ssid,
|
||||||
.get_ssid = bsd_get_ssid,
|
.hapd_get_ssid = bsd_get_ssid,
|
||||||
.set_countermeasures = bsd_set_countermeasures,
|
.set_countermeasures = bsd_set_countermeasures,
|
||||||
.sta_clear_stats = bsd_sta_clear_stats,
|
.sta_clear_stats = bsd_sta_clear_stats,
|
||||||
.commit = bsd_commit,
|
.commit = bsd_commit,
|
||||||
#ifdef CONFIG_DRIVER_RADIUS_ACL
|
#ifdef CONFIG_DRIVER_RADIUS_ACL_NOT_YET
|
||||||
.set_radius_acl_auth = bsd_set_radius_acl_auth,
|
.set_radius_acl_auth = bsd_set_radius_acl_auth,
|
||||||
.set_radius_acl_expire = bsd_set_radius_acl_expire,
|
.set_radius_acl_expire = bsd_set_radius_acl_expire,
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
.PATH.c:${WPA_SUPPLICANT_DISTDIR}
|
.PATH.c:${WPA_SUPPLICANT_DISTDIR}
|
||||||
|
|
||||||
PROG= wpa_passphrase
|
PROG= wpa_passphrase
|
||||||
SRCS= wpa_passphrase.c sha1.c md5.c
|
SRCS= wpa_passphrase.c sha1.c sha1-internal.c sha1-pbkdf2.c \
|
||||||
|
md5.c md5-internal.c
|
||||||
|
|
||||||
CFLAGS+= -DINTERNAL_SHA1
|
CFLAGS+= -DINTERNAL_SHA1
|
||||||
CFLAGS+= -DINTERNAL_MD5
|
CFLAGS+= -DINTERNAL_MD5
|
||||||
|
|
|
@ -6,11 +6,15 @@
|
||||||
${WPA_DISTDIR}/src/drivers \
|
${WPA_DISTDIR}/src/drivers \
|
||||||
${WPA_DISTDIR}/src/eap_peer \
|
${WPA_DISTDIR}/src/eap_peer \
|
||||||
${WPA_DISTDIR}/src/rsn_supp
|
${WPA_DISTDIR}/src/rsn_supp
|
||||||
|
${WPA_DISTDIR}/src/crypto
|
||||||
|
|
||||||
PROG= wpa_supplicant
|
PROG= wpa_supplicant
|
||||||
SRCS= aes.c aes_wrap.c blacklist.c common.c config.c ctrl_iface.c \
|
SRCS= aes-cbc.c aes-ctr.c aes-eax.c aes-encblock.c \
|
||||||
|
aes-internal.c aes-omac1.c aes-unwrap.c \
|
||||||
|
aes-wrap.c bss.c blacklist.c common.c config.c ctrl_iface.c \
|
||||||
ctrl_iface_unix.c drivers.c eloop.c events.c l2_packet_freebsd.c main.c\
|
ctrl_iface_unix.c drivers.c eloop.c events.c l2_packet_freebsd.c main.c\
|
||||||
md5.c preauth.c pmksa_cache.c rc4.c scan.c scan_helpers.c sha1.c \
|
md5.c notify.c preauth.c pmksa_cache.c scan.c \
|
||||||
|
sha1-pbkdf2.c sha1-tlsprf.c sha1-tprf.c sha1.c \
|
||||||
wpa.c wpa_common.c wpa_debug.c wpa_ie.c wpa_supplicant.c \
|
wpa.c wpa_common.c wpa_debug.c wpa_ie.c wpa_supplicant.c \
|
||||||
wpabuf.c wpas_glue.c \
|
wpabuf.c wpas_glue.c \
|
||||||
driver_ndis.c Packet32.c \
|
driver_ndis.c Packet32.c \
|
||||||
|
@ -34,7 +38,7 @@ CFLAGS+= -DCONFIG_DRIVER_NDIS
|
||||||
CFLAGS+= -DCONFIG_DRIVER_WIRED
|
CFLAGS+= -DCONFIG_DRIVER_WIRED
|
||||||
CFLAGS+= -DCONFIG_TERMINATE_ONLASTIF
|
CFLAGS+= -DCONFIG_TERMINATE_ONLASTIF
|
||||||
CFLAGS+= -DCONFIG_DEBUG_SYSLOG
|
CFLAGS+= -DCONFIG_DEBUG_SYSLOG
|
||||||
CFLAGS+= -g
|
#CFLAGS+= -g
|
||||||
DPADD+= ${LIBPCAP}
|
DPADD+= ${LIBPCAP}
|
||||||
LDADD+= -lpcap
|
LDADD+= -lpcap
|
||||||
|
|
||||||
|
@ -49,7 +53,7 @@ LDADD+=${WPA_SUPPLICANT_LDADD}
|
||||||
#LDFLAGS+=${WPA_SUPPLICANT_LDFLAGS}
|
#LDFLAGS+=${WPA_SUPPLICANT_LDFLAGS}
|
||||||
|
|
||||||
.if ${MK_WPA_SUPPLICANT_EAPOL} != "no"
|
.if ${MK_WPA_SUPPLICANT_EAPOL} != "no"
|
||||||
SRCS+= eapol_supp_sm.c eap.c eap_common.c eap_methods.c
|
SRCS+= eapol_supp_sm.c eap.c eap_common.c eap_methods.c eap_register.c
|
||||||
CFLAGS+= -DIEEE8021X_EAPOL
|
CFLAGS+= -DIEEE8021X_EAPOL
|
||||||
|
|
||||||
.if ${MK_OPENSSL} != "no" && !defined(RELEASE_CRUNCH)
|
.if ${MK_OPENSSL} != "no" && !defined(RELEASE_CRUNCH)
|
||||||
|
|
|
@ -220,7 +220,7 @@ wpa_driver_bsd_set_ssid(void *priv, const char *ssid,
|
||||||
|
|
||||||
static int
|
static int
|
||||||
wpa_driver_bsd_set_wpa_ie(struct wpa_driver_bsd_data *drv,
|
wpa_driver_bsd_set_wpa_ie(struct wpa_driver_bsd_data *drv,
|
||||||
const char *wpa_ie, size_t wpa_ie_len)
|
const u8 *wpa_ie, size_t wpa_ie_len)
|
||||||
{
|
{
|
||||||
struct ieee80211req ireq;
|
struct ieee80211req ireq;
|
||||||
|
|
||||||
|
@ -258,14 +258,6 @@ wpa_driver_bsd_set_wpa_internal(void *priv, int wpa, int privacy)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
wpa_driver_bsd_set_wpa(void *priv, int enabled)
|
|
||||||
{
|
|
||||||
wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
|
|
||||||
|
|
||||||
return wpa_driver_bsd_set_wpa_internal(priv, enabled ? 3 : 0, enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
wpa_driver_bsd_del_key(struct wpa_driver_bsd_data *drv, int key_idx,
|
wpa_driver_bsd_del_key(struct wpa_driver_bsd_data *drv, int key_idx,
|
||||||
const unsigned char *addr)
|
const unsigned char *addr)
|
||||||
|
@ -290,7 +282,7 @@ wpa_driver_bsd_del_key(struct wpa_driver_bsd_data *drv, int key_idx,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
wpa_driver_bsd_set_key(void *priv, wpa_alg alg,
|
wpa_driver_bsd_set_key(const char *ifname, void *priv, enum wpa_alg alg,
|
||||||
const unsigned char *addr, int key_idx, int set_tx,
|
const unsigned char *addr, int key_idx, int set_tx,
|
||||||
const u8 *seq, size_t seq_len,
|
const u8 *seq, size_t seq_len,
|
||||||
const u8 *key, size_t key_len)
|
const u8 *key, size_t key_len)
|
||||||
|
@ -392,6 +384,26 @@ wpa_driver_bsd_set_drop_unencrypted(void *priv, int enabled)
|
||||||
return set80211param(drv, IEEE80211_IOC_DROPUNENCRYPTED, enabled);
|
return set80211param(drv, IEEE80211_IOC_DROPUNENCRYPTED, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 & WPA_AUTH_ALG_OPEN) &&
|
||||||
|
(auth_alg & WPA_AUTH_ALG_SHARED))
|
||||||
|
authmode = IEEE80211_AUTH_AUTO;
|
||||||
|
else if (auth_alg & WPA_AUTH_ALG_SHARED)
|
||||||
|
authmode = IEEE80211_AUTH_SHARED;
|
||||||
|
else
|
||||||
|
authmode = IEEE80211_AUTH_OPEN;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "%s alg 0x%x authmode %u",
|
||||||
|
__func__, auth_alg, authmode);
|
||||||
|
|
||||||
|
return set80211param(drv, IEEE80211_IOC_AUTHMODE, authmode);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
wpa_driver_bsd_deauthenticate(void *priv, const u8 *addr, int reason_code)
|
wpa_driver_bsd_deauthenticate(void *priv, const u8 *addr, int reason_code)
|
||||||
{
|
{
|
||||||
|
@ -452,6 +464,11 @@ wpa_driver_bsd_associate(void *priv, struct wpa_driver_associate_params *params)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wpa_driver_bsd_set_drop_unencrypted(drv, params->drop_unencrypted)
|
||||||
|
< 0)
|
||||||
|
return -1;
|
||||||
|
if (wpa_driver_bsd_set_auth_alg(drv, params->auth_alg) < 0)
|
||||||
|
return -1;
|
||||||
/* XXX error handling is wrong but unclear what to do... */
|
/* 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)
|
if (wpa_driver_bsd_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -485,30 +502,11 @@ wpa_driver_bsd_associate(void *priv, struct wpa_driver_associate_params *params)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
wpa_driver_bsd_set_auth_alg(void *priv, int auth_alg)
|
wpa_driver_bsd_scan(void *priv, struct wpa_driver_scan_params *params)
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "%s alg 0x%x authmode %u",
|
|
||||||
__func__, auth_alg, authmode);
|
|
||||||
|
|
||||||
return set80211param(drv, IEEE80211_IOC_AUTHMODE, authmode);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
wpa_driver_bsd_scan(void *priv, const u8 *ssid, size_t ssid_len)
|
|
||||||
{
|
{
|
||||||
struct wpa_driver_bsd_data *drv = priv;
|
struct wpa_driver_bsd_data *drv = priv;
|
||||||
struct ieee80211_scan_req sr;
|
struct ieee80211_scan_req sr;
|
||||||
|
int i;
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
/* XXX not true but easiest to perpetuate the myth */
|
/* XXX not true but easiest to perpetuate the myth */
|
||||||
|
@ -529,30 +527,21 @@ wpa_driver_bsd_scan(void *priv, const u8 *ssid, size_t ssid_len)
|
||||||
| IEEE80211_IOC_SCAN_NOJOIN
|
| IEEE80211_IOC_SCAN_NOJOIN
|
||||||
;
|
;
|
||||||
sr.sr_duration = IEEE80211_IOC_SCAN_FOREVER;
|
sr.sr_duration = IEEE80211_IOC_SCAN_FOREVER;
|
||||||
if (ssid_len != 0) {
|
if (params->num_ssids > 0) {
|
||||||
/* XXX ssid_len must be <= IEEE80211_NWID_LEN */
|
sr.sr_nssid = params->num_ssids;
|
||||||
memcpy(sr.sr_ssid[sr.sr_nssid].ssid, ssid, ssid_len);
|
#if 0
|
||||||
sr.sr_ssid[sr.sr_nssid].len = ssid_len;
|
/* Boundary check is done by upper layer */
|
||||||
sr.sr_nssid++;
|
if (sr.sr_nssid > IEEE80211_IOC_SCAN_MAX_SSID)
|
||||||
}
|
sr.sr_nssid = IEEE80211_IOC_SCAN_MAX_SSID;
|
||||||
if (drv->lastssid_len != 0 &&
|
#endif
|
||||||
(drv->lastssid_len != ssid_len ||
|
/* NB: check scan cache first */
|
||||||
memcmp(drv->lastssid, ssid, ssid_len) != 0)) {
|
|
||||||
/*
|
|
||||||
* If we are scanning because we received a deauth
|
|
||||||
* and the scan cache is warm then we'll find the
|
|
||||||
* ap there and short circuit a full-blown scan.
|
|
||||||
*/
|
|
||||||
memcpy(sr.sr_ssid[sr.sr_nssid].ssid, drv->lastssid,
|
|
||||||
drv->lastssid_len);
|
|
||||||
sr.sr_ssid[sr.sr_nssid].len = drv->lastssid_len;
|
|
||||||
sr.sr_nssid++;
|
|
||||||
/* NB: clear so we don't retry w/o associating first */
|
|
||||||
drv->lastssid_len = 0;
|
|
||||||
}
|
|
||||||
if (sr.sr_nssid != 0) /* NB: check scan cache first */
|
|
||||||
sr.sr_flags |= IEEE80211_IOC_SCAN_CHECK;
|
sr.sr_flags |= IEEE80211_IOC_SCAN_CHECK;
|
||||||
|
}
|
||||||
|
for (i = 0; i < sr.sr_nssid; i++) {
|
||||||
|
sr.sr_ssid[i].len = params->ssids[i].ssid_len;
|
||||||
|
os_memcpy(sr.sr_ssid[i].ssid, params->ssids[i].ssid,
|
||||||
|
sr.sr_ssid[i].len);
|
||||||
|
}
|
||||||
/* NB: net80211 delivers a scan complete event so no need to poll */
|
/* NB: net80211 delivers a scan complete event so no need to poll */
|
||||||
return set80211var(drv, IEEE80211_IOC_SCAN_REQ, &sr, sizeof(sr));
|
return set80211var(drv, IEEE80211_IOC_SCAN_REQ, &sr, sizeof(sr));
|
||||||
}
|
}
|
||||||
|
@ -654,40 +643,6 @@ wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compare function for sorting scan results. Return >0 if @b is consider
|
|
||||||
* better. */
|
|
||||||
static int
|
|
||||||
wpa_scan_result_compar(const void *a, const void *b)
|
|
||||||
{
|
|
||||||
const struct wpa_scan_result *wa = a;
|
|
||||||
const struct wpa_scan_result *wb = b;
|
|
||||||
|
|
||||||
/* WPA/WPA2 support preferred */
|
|
||||||
if ((wb->wpa_ie_len || wb->rsn_ie_len) &&
|
|
||||||
!(wa->wpa_ie_len || wa->rsn_ie_len))
|
|
||||||
return 1;
|
|
||||||
if (!(wb->wpa_ie_len || wb->rsn_ie_len) &&
|
|
||||||
(wa->wpa_ie_len || wa->rsn_ie_len))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* privacy support preferred */
|
|
||||||
if ((wa->caps & IEEE80211_CAPINFO_PRIVACY) &&
|
|
||||||
(wb->caps & IEEE80211_CAPINFO_PRIVACY) == 0)
|
|
||||||
return 1;
|
|
||||||
if ((wa->caps & IEEE80211_CAPINFO_PRIVACY) == 0 &&
|
|
||||||
(wb->caps & IEEE80211_CAPINFO_PRIVACY))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* best/max rate preferred if signal level close enough XXX */
|
|
||||||
if (wa->maxrate != wb->maxrate && abs(wb->level - wa->level) < 5)
|
|
||||||
return wb->maxrate - wa->maxrate;
|
|
||||||
|
|
||||||
/* use freq for channel preference */
|
|
||||||
|
|
||||||
/* all things being equal, use signal level */
|
|
||||||
return wb->level - wa->level;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
getmaxrate(const uint8_t rates[15], uint8_t nrates)
|
getmaxrate(const uint8_t rates[15], uint8_t nrates)
|
||||||
{
|
{
|
||||||
|
@ -715,74 +670,97 @@ iswpaoui(const u_int8_t *frm)
|
||||||
return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI);
|
return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
wpa_driver_bsd_get_scan_results(void *priv,
|
static void
|
||||||
struct wpa_scan_result *results,
|
wpa_driver_bsd_add_scan_entry(struct wpa_scan_results *res,
|
||||||
size_t max_size)
|
struct ieee80211req_scan_result *sr)
|
||||||
{
|
{
|
||||||
#define min(a,b) ((a)>(b)?(b):(a))
|
struct wpa_scan_res *result, **tmp;
|
||||||
struct wpa_driver_bsd_data *drv = priv;
|
size_t extra_len;
|
||||||
uint8_t buf[24*1024];
|
u8 *pos;
|
||||||
const uint8_t *cp, *vp;
|
|
||||||
const struct ieee80211req_scan_result *sr;
|
|
||||||
struct wpa_scan_result *wsr;
|
|
||||||
int len, ielen;
|
|
||||||
|
|
||||||
memset(results, 0, max_size * sizeof(struct wpa_scan_result));
|
extra_len = 2 + sr->isr_ssid_len;
|
||||||
|
extra_len += 2 + sr->isr_nrates;
|
||||||
|
extra_len += 3; /* ERP IE */
|
||||||
|
extra_len += sr->isr_ie_len;
|
||||||
|
|
||||||
len = get80211var(drv, IEEE80211_IOC_SCAN_RESULTS, buf, sizeof(buf));
|
result = os_zalloc(sizeof(*result) + extra_len);
|
||||||
if (len < 0)
|
if (result == NULL)
|
||||||
return -1;
|
return;
|
||||||
cp = buf;
|
os_memcpy(result->bssid, sr->isr_bssid, ETH_ALEN);
|
||||||
wsr = results;
|
result->freq = sr->isr_freq;
|
||||||
while (len >= sizeof(struct ieee80211req_scan_result)) {
|
result->beacon_int = sr->isr_intval;
|
||||||
sr = (const struct ieee80211req_scan_result *) cp;
|
result->caps = sr->isr_capinfo;
|
||||||
memcpy(wsr->bssid, sr->isr_bssid, IEEE80211_ADDR_LEN);
|
result->qual = sr->isr_rssi;
|
||||||
wsr->ssid_len = sr->isr_ssid_len;
|
result->noise = sr->isr_noise;
|
||||||
wsr->freq = sr->isr_freq;
|
|
||||||
wsr->noise = sr->isr_noise;
|
|
||||||
wsr->qual = sr->isr_rssi;
|
|
||||||
wsr->level = 0; /* XXX? */
|
|
||||||
wsr->caps = sr->isr_capinfo;
|
|
||||||
wsr->maxrate = getmaxrate(sr->isr_rates, sr->isr_nrates);
|
|
||||||
vp = ((u_int8_t *)sr) + sr->isr_ie_off;
|
|
||||||
memcpy(wsr->ssid, vp, sr->isr_ssid_len);
|
|
||||||
if (sr->isr_ie_len > 0) {
|
|
||||||
vp += sr->isr_ssid_len;
|
|
||||||
ielen = sr->isr_ie_len;
|
|
||||||
while (ielen > 0) {
|
|
||||||
switch (vp[0]) {
|
|
||||||
case IEEE80211_ELEMID_VENDOR:
|
|
||||||
if (!iswpaoui(vp))
|
|
||||||
break;
|
|
||||||
wsr->wpa_ie_len =
|
|
||||||
min(2+vp[1], SSID_MAX_WPA_IE_LEN);
|
|
||||||
memcpy(wsr->wpa_ie, vp, wsr->wpa_ie_len);
|
|
||||||
break;
|
|
||||||
case IEEE80211_ELEMID_RSN:
|
|
||||||
wsr->rsn_ie_len =
|
|
||||||
min(2+vp[1], SSID_MAX_WPA_IE_LEN);
|
|
||||||
memcpy(wsr->rsn_ie, vp, wsr->rsn_ie_len);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ielen -= 2+vp[1];
|
|
||||||
vp += 2+vp[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cp += sr->isr_len, len -= sr->isr_len;
|
pos = (u8 *)(result + 1);
|
||||||
wsr++;
|
|
||||||
}
|
|
||||||
qsort(results, wsr - results, sizeof(struct wpa_scan_result),
|
|
||||||
wpa_scan_result_compar);
|
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "Received %d bytes of scan results (%d BSSes)",
|
*pos++ = WLAN_EID_SSID;
|
||||||
len, wsr - results);
|
*pos++ = sr->isr_ssid_len;
|
||||||
|
os_memcpy(pos, sr + 1, sr->isr_ssid_len);
|
||||||
|
pos += sr->isr_ssid_len;
|
||||||
|
|
||||||
return wsr - results;
|
/*
|
||||||
#undef min
|
* Deal all rates as supported rate.
|
||||||
|
* Because net80211 doesn't report extended supported rate or not.
|
||||||
|
*/
|
||||||
|
*pos++ = WLAN_EID_SUPP_RATES;
|
||||||
|
*pos++ = sr->isr_nrates;
|
||||||
|
os_memcpy(pos, sr->isr_rates, sr->isr_nrates);
|
||||||
|
pos += sr->isr_nrates;
|
||||||
|
|
||||||
|
*pos++ = WLAN_EID_ERP_INFO;
|
||||||
|
*pos++ = 1;
|
||||||
|
*pos++ = sr->isr_erp;
|
||||||
|
|
||||||
|
os_memcpy(pos, (u8 *)(sr + 1) + sr->isr_ssid_len, sr->isr_ie_len);
|
||||||
|
pos += sr->isr_ie_len;
|
||||||
|
|
||||||
|
result->ie_len = pos - (u8 *)(result + 1);
|
||||||
|
|
||||||
|
tmp = os_realloc(res->res,
|
||||||
|
(res->num + 1) * sizeof(struct wpa_scan_res *));
|
||||||
|
if (tmp == NULL) {
|
||||||
|
os_free(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tmp[res->num++] = result;
|
||||||
|
res->res = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct wpa_scan_results *
|
||||||
|
wpa_driver_bsd_get_scan_results2(void *priv)
|
||||||
|
{
|
||||||
|
struct ieee80211req_scan_result *sr;
|
||||||
|
struct wpa_scan_results *res;
|
||||||
|
int len, rest;
|
||||||
|
uint8_t buf[24*1024], *pos;
|
||||||
|
|
||||||
|
len = get80211var(priv, IEEE80211_IOC_SCAN_RESULTS, buf, 24*1024);
|
||||||
|
if (len < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
res = os_zalloc(sizeof(*res));
|
||||||
|
if (res == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
pos = buf;
|
||||||
|
rest = len;
|
||||||
|
while (rest >= sizeof(struct ieee80211req_scan_result)) {
|
||||||
|
sr = (struct ieee80211req_scan_result *)pos;
|
||||||
|
wpa_driver_bsd_add_scan_entry(res, sr);
|
||||||
|
pos += sr->isr_len;
|
||||||
|
rest -= sr->isr_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "Received %d bytes of scan results (%lu BSSes)",
|
||||||
|
len, (unsigned long)res->num);
|
||||||
|
|
||||||
|
return (res);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define GETPARAM(drv, param, v) \
|
#define GETPARAM(drv, param, v) \
|
||||||
(((v) = get80211param(drv, param)) != -1)
|
(((v) = get80211param(drv, param)) != -1)
|
||||||
#define IEEE80211_C_BGSCAN 0x20000000
|
#define IEEE80211_C_BGSCAN 0x20000000
|
||||||
|
@ -941,14 +919,11 @@ struct wpa_driver_ops wpa_driver_bsd_ops = {
|
||||||
.deinit = wpa_driver_bsd_deinit,
|
.deinit = wpa_driver_bsd_deinit,
|
||||||
.get_bssid = wpa_driver_bsd_get_bssid,
|
.get_bssid = wpa_driver_bsd_get_bssid,
|
||||||
.get_ssid = wpa_driver_bsd_get_ssid,
|
.get_ssid = wpa_driver_bsd_get_ssid,
|
||||||
.set_wpa = wpa_driver_bsd_set_wpa,
|
|
||||||
.set_key = wpa_driver_bsd_set_key,
|
.set_key = wpa_driver_bsd_set_key,
|
||||||
.set_countermeasures = wpa_driver_bsd_set_countermeasures,
|
.set_countermeasures = wpa_driver_bsd_set_countermeasures,
|
||||||
.set_drop_unencrypted = wpa_driver_bsd_set_drop_unencrypted,
|
.scan2 = wpa_driver_bsd_scan,
|
||||||
.scan = wpa_driver_bsd_scan,
|
.get_scan_results2 = wpa_driver_bsd_get_scan_results2,
|
||||||
.get_scan_results = wpa_driver_bsd_get_scan_results,
|
|
||||||
.deauthenticate = wpa_driver_bsd_deauthenticate,
|
.deauthenticate = wpa_driver_bsd_deauthenticate,
|
||||||
.disassociate = wpa_driver_bsd_disassociate,
|
.disassociate = wpa_driver_bsd_disassociate,
|
||||||
.associate = wpa_driver_bsd_associate,
|
.associate = wpa_driver_bsd_associate,
|
||||||
.set_auth_alg = wpa_driver_bsd_set_auth_alg,
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue