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"
|
||||
|
||||
.PATH.c:${HOSTAPD_DISTDIR} \
|
||||
${WPA_DISTDIR}/src/ap \
|
||||
${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}
|
||||
|
||||
PROG= hostapd
|
||||
SRCS= accounting.c aes.c aes_wrap.c ap_list.c beacon.c common.c \
|
||||
config.c ctrl_iface.c drivers.c eapol_sm.c eap.c eap_common.c \
|
||||
eap_identity.c eap_methods.c eloop.c hostapd.c \
|
||||
hw_features.c ieee802_11.c ieee802_11_common.c ieee802_11_auth.c \
|
||||
ieee802_1x.c ip_addr.c md5.c mlme.c pmksa_cache.c radius.c \
|
||||
radius_client.c rc4.c sha1.c sta_info.c vlan_init.c wme.c \
|
||||
wpa.c wpa_auth_ie.c wpa_common.c wpa_debug.c wpabuf.c
|
||||
SRCS= accounting.c aes-wrap.c ap_config.c \
|
||||
ap_drv_ops.c ap_mlme.c authsrv.c \
|
||||
chap.c common.c config_file.c ctrl_iface.c crypto_openssl.c \
|
||||
ctrl_iface_ap.c drivers.c drv_callbacks.c dump_state.c \
|
||||
eap_common.c eap_peap_common.c eap_register.c eap_server.c \
|
||||
eap_server_gtc.c eap_server_identity.c eap_server_md5.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
|
||||
|
||||
MAN= hostapd.8 hostapd.conf.5
|
||||
@ -24,16 +38,16 @@ FILESDIR= ${SHAREDIR}/examples/hostapd
|
||||
FILES= hostapd.conf hostapd.eap_user hostapd.wpa_psk
|
||||
.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
|
||||
.if ${MK_INET6} != "no"
|
||||
CFLAGS+= -DCONFIG_IPV6
|
||||
.endif
|
||||
CFLAGS+= -g
|
||||
DPADD+= ${LIBPCAP}
|
||||
LDADD+= -lpcap
|
||||
#CFLAGS+= -g
|
||||
DPADD+= ${LIBPCAP} ${LIBSSL}
|
||||
LDADD+= -lpcap -lssl
|
||||
|
||||
# User customizations for wpa_supplicant/hostapd build environment
|
||||
CFLAGS+=${HOSTAPD_CFLAGS}
|
||||
|
@ -14,12 +14,13 @@
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include "includes.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 <net/if.h>
|
||||
@ -32,34 +33,29 @@
|
||||
#undef WPA_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 "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 hostapd_data *hapd; /* back pointer */
|
||||
struct hostapd_data *hapd; /* back pointer */
|
||||
|
||||
char iface[IFNAMSIZ + 1];
|
||||
unsigned int ifindex; /* interface index */
|
||||
struct l2_packet_data *sock_xmit; /* raw packet xmit socket */
|
||||
int ioctl_sock; /* socket for ioctl() use */
|
||||
int wext_sock; /* socket for wireless events */
|
||||
int ioctl_sock; /* open socket for 802.11 ioctls */
|
||||
int wext_sock;
|
||||
struct l2_packet_data *sock_xmit;/* raw packet xmit socket */
|
||||
int route; /* routing socket for 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 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
|
||||
set80211var(struct bsd_driver_data *drv, int op, const void *arg, int arg_len)
|
||||
@ -171,44 +167,37 @@ bsd_commit(void *priv)
|
||||
}
|
||||
|
||||
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;
|
||||
struct hostapd_data *hapd = drv->hapd;
|
||||
struct hostapd_bss_config *conf = hapd->conf;
|
||||
wpa_printf(MSG_DEBUG, "%s: enabled=%d\n", __func__, params->enabled);
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s: enabled=%d\n", __func__, enabled);
|
||||
|
||||
if (!enabled) {
|
||||
if (!params->enabled) {
|
||||
/* XXX restore state */
|
||||
return set80211param(priv, IEEE80211_IOC_AUTHMODE,
|
||||
IEEE80211_AUTH_AUTO);
|
||||
}
|
||||
if (!conf->wpa && !conf->ieee802_1x) {
|
||||
hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER,
|
||||
HOSTAPD_LEVEL_WARNING, "No 802.1X or WPA enabled!");
|
||||
if (!params->wpa && !params->ieee802_1x) {
|
||||
wpa_printf(MSG_ERROR, "%s: No 802.1X or WPA enabled",
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
if (conf->wpa && set80211param(drv, IEEE80211_IOC_WPA, conf->wpa)) {
|
||||
hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER,
|
||||
HOSTAPD_LEVEL_WARNING, "Error configuring WPA state!");
|
||||
if (params->wpa && set80211param(priv,IEEE80211_IOC_WPA, params->wpa)) {
|
||||
wpa_printf(MSG_ERROR, "%s: Failed to configure WPA state",
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
if (set80211param(priv, IEEE80211_IOC_AUTHMODE,
|
||||
(conf->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) {
|
||||
hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER,
|
||||
HOSTAPD_LEVEL_WARNING, "Error enabling WPA/802.1X!");
|
||||
(params->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) {
|
||||
wpa_printf(MSG_ERROR, "%s: Failed to enable WPA/802.1X",
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
/* 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);
|
||||
if (!(flags_and & WLAN_STA_AUTHORIZED))
|
||||
if (!(flags_and & WPA_STA_AUTHORIZED))
|
||||
return bsd_set_sta_authorized(priv, addr, 0);
|
||||
return 0;
|
||||
}
|
||||
@ -267,53 +256,64 @@ bsd_del_key(void *priv, const unsigned char *addr, int key_idx)
|
||||
}
|
||||
|
||||
static int
|
||||
bsd_set_key(const char *ifname, void *priv, const char *alg,
|
||||
const u8 *addr, int key_idx,
|
||||
const u8 *key, size_t key_len, int txkey)
|
||||
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 bsd_driver_data *drv = priv;
|
||||
struct hostapd_data *hapd = drv->hapd;
|
||||
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);
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s: alg=%s addr=%s key_idx=%d\n",
|
||||
__func__, alg, ether_sprintf(addr), key_idx);
|
||||
|
||||
if (strcmp(alg, "WEP") == 0)
|
||||
cipher = IEEE80211_CIPHER_WEP;
|
||||
else if (strcmp(alg, "TKIP") == 0)
|
||||
cipher = IEEE80211_CIPHER_TKIP;
|
||||
else if (strcmp(alg, "CCMP") == 0)
|
||||
cipher = IEEE80211_CIPHER_AES_CCM;
|
||||
else {
|
||||
printf("%s: unknown/unsupported algorithm %s\n",
|
||||
__func__, alg);
|
||||
os_memset(&wk, 0, sizeof(wk));
|
||||
switch (alg) {
|
||||
case WPA_ALG_WEP:
|
||||
wk.ik_type = IEEE80211_CIPHER_WEP;
|
||||
break;
|
||||
case WPA_ALG_TKIP:
|
||||
wk.ik_type = IEEE80211_CIPHER_TKIP;
|
||||
break;
|
||||
case WPA_ALG_CCMP:
|
||||
wk.ik_type = IEEE80211_CIPHER_AES_CCM;
|
||||
break;
|
||||
default:
|
||||
wpa_printf(MSG_ERROR, "%s: unknown alg=%d", __func__, alg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (key_len > sizeof(wk.ik_keydata)) {
|
||||
printf("%s: key length %d too big\n", __func__, key_len);
|
||||
return -3;
|
||||
}
|
||||
wk.ik_flags = IEEE80211_KEY_RECV;
|
||||
if (set_tx)
|
||||
wk.ik_flags |= IEEE80211_KEY_XMIT;
|
||||
|
||||
memset(&wk, 0, sizeof(wk));
|
||||
wk.ik_type = cipher;
|
||||
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_flags = IEEE80211_KEY_XMIT
|
||||
| IEEE80211_KEY_GROUP
|
||||
| IEEE80211_KEY_DEFAULT;
|
||||
} else {
|
||||
memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
|
||||
wk.ik_keyix = IEEE80211_KEYIX_NONE;
|
||||
wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT;
|
||||
os_memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
|
||||
/*
|
||||
* 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;
|
||||
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));
|
||||
}
|
||||
@ -355,7 +355,7 @@ bsd_flush(void *priv)
|
||||
u8 allsta[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
|
||||
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 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
|
||||
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 hostapd_data *hapd = drv->hapd;
|
||||
@ -432,7 +432,7 @@ bsd_sta_deauth(void *priv, const u8 *addr, int reason_code)
|
||||
}
|
||||
|
||||
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 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));
|
||||
}
|
||||
|
||||
static int
|
||||
bsd_del_sta(struct bsd_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN])
|
||||
static void
|
||||
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;
|
||||
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.
|
||||
*/
|
||||
if (conf->wpa) {
|
||||
memset(&ie, 0, sizeof(ie));
|
||||
memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN);
|
||||
if (get80211var(drv, IEEE80211_IOC_WPAIE, &ie, sizeof(ie)) < 0) {
|
||||
printf("Failed to get WPA/RSN information element.\n");
|
||||
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;
|
||||
}
|
||||
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");
|
||||
goto no_ie;
|
||||
}
|
||||
iebuf = ie.wpa_ie;
|
||||
ielen = ie.wpa_ie[1];
|
||||
if (ielen == 0)
|
||||
iebuf = NULL;
|
||||
else
|
||||
ielen += 2;
|
||||
|
||||
/*
|
||||
* Now that the internal station state is setup
|
||||
* 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);
|
||||
no_ie:
|
||||
drv_event_assoc(ctx, addr, iebuf, ielen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <net/route.h>
|
||||
@ -545,6 +492,7 @@ bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx)
|
||||
struct ieee80211_auth_event *auth;
|
||||
#endif
|
||||
int n;
|
||||
union wpa_event_data data;
|
||||
|
||||
n = read(sock, buf, sizeof(buf));
|
||||
if (n < 0) {
|
||||
@ -576,14 +524,14 @@ bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx)
|
||||
break;
|
||||
case RTM_IEEE80211_LEAVE:
|
||||
leave = (struct ieee80211_leave_event *) &ifan[1];
|
||||
bsd_del_sta(drv, leave->iev_addr);
|
||||
drv_event_disassoc(drv->hapd, leave->iev_addr);
|
||||
break;
|
||||
case RTM_IEEE80211_JOIN:
|
||||
#ifdef RTM_IEEE80211_REJOIN
|
||||
case RTM_IEEE80211_REJOIN:
|
||||
#endif
|
||||
join = (struct ieee80211_join_event *) &ifan[1];
|
||||
bsd_new_sta(drv, join->iev_addr);
|
||||
bsd_new_sta(drv, drv->hapd, join->iev_addr);
|
||||
break;
|
||||
case RTM_IEEE80211_REPLAY:
|
||||
/* ignore */
|
||||
@ -594,9 +542,13 @@ bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx)
|
||||
"Michael MIC failure wireless event: "
|
||||
"keyix=%u src_addr=" MACSTR, mic->iev_keyix,
|
||||
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;
|
||||
#ifdef CONFIG_DRIVER_RADIUS_ACL
|
||||
#ifdef CONFIG_DRIVER_RADIUS_ACL_NOT_YET
|
||||
case RTM_IEEE80211_AUTH:
|
||||
auth = (struct ieee80211_auth_event *) &ifan[1];
|
||||
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
|
||||
bsd_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len,
|
||||
int encrypt, const u8 *own_addr)
|
||||
|
||||
{
|
||||
struct bsd_driver_data *drv = priv;
|
||||
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)
|
||||
{
|
||||
struct bsd_driver_data *drv = ctx;
|
||||
struct hostapd_data *hapd = drv->hapd;
|
||||
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));
|
||||
drv_event_eapol_rx(drv->hapd, src_addr, buf, len);
|
||||
}
|
||||
|
||||
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 hostapd_data *hapd = drv->hapd;
|
||||
|
||||
int ssid_len = get80211var(priv, IEEE80211_IOC_SSID, buf, len);
|
||||
|
||||
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
|
||||
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 hostapd_data *hapd = drv->hapd;
|
||||
@ -752,7 +661,7 @@ bsd_set_countermeasures(void *priv, int enabled)
|
||||
return set80211param(drv, IEEE80211_IOC_COUNTERMEASURES, enabled);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DRIVER_RADIUS_ACL
|
||||
#ifdef CONFIG_DRIVER_RADIUS_ACL_NOT_YET
|
||||
static int
|
||||
bsd_set_radius_acl_auth(void *priv, const u8 *mac, int accepted,
|
||||
u32 session_timeout)
|
||||
@ -814,24 +723,23 @@ bsd_set_radius_acl_expire(void *priv, const u8 *mac)
|
||||
#endif /* CONFIG_DRIVER_RADIUS_ACL */
|
||||
|
||||
static void *
|
||||
bsd_init(struct hostapd_data *hapd)
|
||||
bsd_init(struct hostapd_data *hapd, struct wpa_init_params *params)
|
||||
{
|
||||
struct bsd_driver_data *drv;
|
||||
|
||||
drv = malloc(sizeof(struct bsd_driver_data));
|
||||
drv = os_zalloc(sizeof(struct bsd_driver_data));
|
||||
if (drv == NULL) {
|
||||
printf("Could not allocate memory for bsd driver data\n");
|
||||
goto bad;
|
||||
}
|
||||
|
||||
memset(drv, 0, sizeof(*drv));
|
||||
drv->hapd = hapd;
|
||||
drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
if (drv->ioctl_sock < 0) {
|
||||
perror("socket[PF_INET,SOCK_DGRAM]");
|
||||
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.
|
||||
* This implies we do not support having wpa_supplicant
|
||||
@ -849,10 +757,20 @@ bsd_init(struct hostapd_data *hapd)
|
||||
handle_read, drv, 1);
|
||||
if (drv->sock_xmit == NULL)
|
||||
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;
|
||||
|
||||
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;
|
||||
bad:
|
||||
@ -872,6 +790,10 @@ bsd_deinit(void *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);
|
||||
if (drv->ioctl_sock >= 0)
|
||||
close(drv->ioctl_sock);
|
||||
@ -882,27 +804,25 @@ bsd_deinit(void *priv)
|
||||
|
||||
const struct wpa_driver_ops wpa_driver_bsd_ops = {
|
||||
.name = "bsd",
|
||||
.init = bsd_init,
|
||||
.deinit = bsd_deinit,
|
||||
.hapd_init = bsd_init,
|
||||
.hapd_deinit = bsd_deinit,
|
||||
.set_ieee8021x = bsd_set_ieee8021x,
|
||||
.set_privacy = bsd_set_privacy,
|
||||
.set_encryption = bsd_set_key,
|
||||
.set_key = bsd_set_key,
|
||||
.get_seqnum = bsd_get_seqnum,
|
||||
.flush = bsd_flush,
|
||||
.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,
|
||||
.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_deauth = bsd_sta_deauth,
|
||||
.set_ssid = bsd_set_ssid,
|
||||
.get_ssid = bsd_get_ssid,
|
||||
.hapd_set_ssid = bsd_set_ssid,
|
||||
.hapd_get_ssid = bsd_get_ssid,
|
||||
.set_countermeasures = bsd_set_countermeasures,
|
||||
.sta_clear_stats = bsd_sta_clear_stats,
|
||||
.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_expire = bsd_set_radius_acl_expire,
|
||||
#endif
|
||||
|
@ -5,7 +5,8 @@
|
||||
.PATH.c:${WPA_SUPPLICANT_DISTDIR}
|
||||
|
||||
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_MD5
|
||||
|
@ -6,11 +6,15 @@
|
||||
${WPA_DISTDIR}/src/drivers \
|
||||
${WPA_DISTDIR}/src/eap_peer \
|
||||
${WPA_DISTDIR}/src/rsn_supp
|
||||
${WPA_DISTDIR}/src/crypto
|
||||
|
||||
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\
|
||||
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 \
|
||||
wpabuf.c wpas_glue.c \
|
||||
driver_ndis.c Packet32.c \
|
||||
@ -34,7 +38,7 @@ CFLAGS+= -DCONFIG_DRIVER_NDIS
|
||||
CFLAGS+= -DCONFIG_DRIVER_WIRED
|
||||
CFLAGS+= -DCONFIG_TERMINATE_ONLASTIF
|
||||
CFLAGS+= -DCONFIG_DEBUG_SYSLOG
|
||||
CFLAGS+= -g
|
||||
#CFLAGS+= -g
|
||||
DPADD+= ${LIBPCAP}
|
||||
LDADD+= -lpcap
|
||||
|
||||
@ -49,7 +53,7 @@ LDADD+=${WPA_SUPPLICANT_LDADD}
|
||||
#LDFLAGS+=${WPA_SUPPLICANT_LDFLAGS}
|
||||
|
||||
.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
|
||||
|
||||
.if ${MK_OPENSSL} != "no" && !defined(RELEASE_CRUNCH)
|
||||
|
@ -220,7 +220,7 @@ wpa_driver_bsd_set_ssid(void *priv, const char *ssid,
|
||||
|
||||
static int
|
||||
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;
|
||||
|
||||
@ -258,14 +258,6 @@ wpa_driver_bsd_set_wpa_internal(void *priv, int wpa, int privacy)
|
||||
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
|
||||
wpa_driver_bsd_del_key(struct wpa_driver_bsd_data *drv, int key_idx,
|
||||
const unsigned char *addr)
|
||||
@ -290,7 +282,7 @@ wpa_driver_bsd_del_key(struct wpa_driver_bsd_data *drv, int key_idx,
|
||||
}
|
||||
|
||||
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 u8 *seq, size_t seq_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);
|
||||
}
|
||||
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
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... */
|
||||
if (wpa_driver_bsd_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0)
|
||||
return -1;
|
||||
@ -485,30 +502,11 @@ wpa_driver_bsd_associate(void *priv, struct wpa_driver_associate_params *params)
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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)
|
||||
wpa_driver_bsd_scan(void *priv, struct wpa_driver_scan_params *params)
|
||||
{
|
||||
struct wpa_driver_bsd_data *drv = priv;
|
||||
struct ieee80211_scan_req sr;
|
||||
int i;
|
||||
int flags;
|
||||
|
||||
/* 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
|
||||
;
|
||||
sr.sr_duration = IEEE80211_IOC_SCAN_FOREVER;
|
||||
if (ssid_len != 0) {
|
||||
/* XXX ssid_len must be <= IEEE80211_NWID_LEN */
|
||||
memcpy(sr.sr_ssid[sr.sr_nssid].ssid, ssid, ssid_len);
|
||||
sr.sr_ssid[sr.sr_nssid].len = ssid_len;
|
||||
sr.sr_nssid++;
|
||||
}
|
||||
if (drv->lastssid_len != 0 &&
|
||||
(drv->lastssid_len != ssid_len ||
|
||||
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 */
|
||||
if (params->num_ssids > 0) {
|
||||
sr.sr_nssid = params->num_ssids;
|
||||
#if 0
|
||||
/* Boundary check is done by upper layer */
|
||||
if (sr.sr_nssid > IEEE80211_IOC_SCAN_MAX_SSID)
|
||||
sr.sr_nssid = IEEE80211_IOC_SCAN_MAX_SSID;
|
||||
#endif
|
||||
/* NB: check scan cache first */
|
||||
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 */
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
||||
static int
|
||||
wpa_driver_bsd_get_scan_results(void *priv,
|
||||
struct wpa_scan_result *results,
|
||||
size_t max_size)
|
||||
|
||||
static void
|
||||
wpa_driver_bsd_add_scan_entry(struct wpa_scan_results *res,
|
||||
struct ieee80211req_scan_result *sr)
|
||||
{
|
||||
#define min(a,b) ((a)>(b)?(b):(a))
|
||||
struct wpa_driver_bsd_data *drv = priv;
|
||||
uint8_t buf[24*1024];
|
||||
const uint8_t *cp, *vp;
|
||||
const struct ieee80211req_scan_result *sr;
|
||||
struct wpa_scan_result *wsr;
|
||||
int len, ielen;
|
||||
struct wpa_scan_res *result, **tmp;
|
||||
size_t extra_len;
|
||||
u8 *pos;
|
||||
|
||||
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));
|
||||
if (len < 0)
|
||||
return -1;
|
||||
cp = buf;
|
||||
wsr = results;
|
||||
while (len >= sizeof(struct ieee80211req_scan_result)) {
|
||||
sr = (const struct ieee80211req_scan_result *) cp;
|
||||
memcpy(wsr->bssid, sr->isr_bssid, IEEE80211_ADDR_LEN);
|
||||
wsr->ssid_len = sr->isr_ssid_len;
|
||||
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];
|
||||
}
|
||||
}
|
||||
result = os_zalloc(sizeof(*result) + extra_len);
|
||||
if (result == NULL)
|
||||
return;
|
||||
os_memcpy(result->bssid, sr->isr_bssid, ETH_ALEN);
|
||||
result->freq = sr->isr_freq;
|
||||
result->beacon_int = sr->isr_intval;
|
||||
result->caps = sr->isr_capinfo;
|
||||
result->qual = sr->isr_rssi;
|
||||
result->noise = sr->isr_noise;
|
||||
|
||||
cp += sr->isr_len, len -= sr->isr_len;
|
||||
wsr++;
|
||||
}
|
||||
qsort(results, wsr - results, sizeof(struct wpa_scan_result),
|
||||
wpa_scan_result_compar);
|
||||
pos = (u8 *)(result + 1);
|
||||
|
||||
wpa_printf(MSG_DEBUG, "Received %d bytes of scan results (%d BSSes)",
|
||||
len, wsr - results);
|
||||
*pos++ = WLAN_EID_SSID;
|
||||
*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) \
|
||||
(((v) = get80211param(drv, param)) != -1)
|
||||
#define IEEE80211_C_BGSCAN 0x20000000
|
||||
@ -941,14 +919,11 @@ struct wpa_driver_ops wpa_driver_bsd_ops = {
|
||||
.deinit = wpa_driver_bsd_deinit,
|
||||
.get_bssid = wpa_driver_bsd_get_bssid,
|
||||
.get_ssid = wpa_driver_bsd_get_ssid,
|
||||
.set_wpa = wpa_driver_bsd_set_wpa,
|
||||
.set_key = wpa_driver_bsd_set_key,
|
||||
.set_countermeasures = wpa_driver_bsd_set_countermeasures,
|
||||
.set_drop_unencrypted = wpa_driver_bsd_set_drop_unencrypted,
|
||||
.scan = wpa_driver_bsd_scan,
|
||||
.get_scan_results = wpa_driver_bsd_get_scan_results,
|
||||
.scan2 = wpa_driver_bsd_scan,
|
||||
.get_scan_results2 = wpa_driver_bsd_get_scan_results2,
|
||||
.deauthenticate = wpa_driver_bsd_deauthenticate,
|
||||
.disassociate = wpa_driver_bsd_disassociate,
|
||||
.associate = wpa_driver_bsd_associate,
|
||||
.set_auth_alg = wpa_driver_bsd_set_auth_alg,
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user