Adapt for wpa_supplicant / hostapd 0.7.3.

This commit is contained in:
Rui Paulo 2010-11-03 10:44:25 +00:00
parent e28a4053b1
commit 5d6ccd39d5
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=214735
5 changed files with 306 additions and 392 deletions

View File

@ -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}

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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,
};