#include "common.h"
#include "common/wpa_ctrl.h"
+#include "utils/eloop.h"
#include "l2_packet/l2_packet.h"
#include "rsn_supp/wpa.h"
#include "rsn_supp/wpa_ie.h"
#include "ibss_rsn.h"
+static void ibss_rsn_auth_timeout(void *eloop_ctx, void *timeout_ctx);
+
+
static struct ibss_rsn_peer * ibss_rsn_get_peer(struct ibss_rsn *ibss_rsn,
const u8 *addr)
{
static void ibss_rsn_free(struct ibss_rsn_peer *peer)
{
+ eloop_cancel_timeout(ibss_rsn_auth_timeout, peer, NULL);
wpa_auth_sta_deinit(peer->auth);
wpa_sm_deinit(peer->supp);
os_free(peer);
if (wpa_s->l2)
return l2_packet_send(wpa_s->l2, dest, proto, buf, len);
- return wpa_drv_send_eapol(wpa_s, dest, proto, buf, len);
+ return -1;
}
wpa_sm_set_param(peer->supp, WPA_PARAM_PAIRWISE, WPA_CIPHER_CCMP);
wpa_sm_set_param(peer->supp, WPA_PARAM_GROUP, WPA_CIPHER_CCMP);
wpa_sm_set_param(peer->supp, WPA_PARAM_KEY_MGMT, WPA_KEY_MGMT_PSK);
- wpa_sm_set_pmk(peer->supp, psk, PMK_LEN);
+ wpa_sm_set_pmk(peer->supp, psk, PMK_LEN, NULL, NULL);
peer->supp_ie_len = sizeof(peer->supp_ie);
if (wpa_sm_set_assoc_wpa_ie_default(peer->supp, peer->supp_ie,
}
-static const u8 * auth_get_psk(void *ctx, const u8 *addr, const u8 *prev_psk)
+static const u8 * auth_get_psk(void *ctx, const u8 *addr,
+ const u8 *p2p_dev_addr, const u8 *prev_psk)
{
struct ibss_rsn *ibss_rsn = ctx;
wpa_printf(MSG_DEBUG, "AUTH: %s (addr=" MACSTR " prev_psk=%p)",
return l2_packet_send(wpa_s->l2, addr, ETH_P_EAPOL, data,
data_len);
- return wpa_drv_send_eapol(wpa_s, addr, ETH_P_EAPOL, data, data_len);
+ return -1;
}
static int ibss_rsn_auth_init(struct ibss_rsn *ibss_rsn,
struct ibss_rsn_peer *peer)
{
- peer->auth = wpa_auth_sta_init(ibss_rsn->auth_group, peer->addr);
+ peer->auth = wpa_auth_sta_init(ibss_rsn->auth_group, peer->addr, NULL);
if (peer->auth == NULL) {
wpa_printf(MSG_DEBUG, "AUTH: wpa_auth_sta_init() failed");
return -1;
}
+static void ibss_rsn_auth_timeout(void *eloop_ctx, void *timeout_ctx)
+{
+ struct ibss_rsn_peer *peer = eloop_ctx;
+
+ /*
+ * Assume peer does not support Authentication exchange or the frame was
+ * lost somewhere - start EAPOL Authenticator.
+ */
+ wpa_printf(MSG_DEBUG,
+ "RSN: Timeout on waiting Authentication frame response from "
+ MACSTR " - start authenticator", MAC2STR(peer->addr));
+
+ peer->authentication_status |= IBSS_RSN_AUTH_BY_US;
+ ibss_rsn_auth_init(peer->ibss_rsn, peer);
+}
+
+
int ibss_rsn_start(struct ibss_rsn *ibss_rsn, const u8 *addr)
{
struct ibss_rsn_peer *peer;
int res;
+ if (!ibss_rsn)
+ return -1;
+
/* if the peer already exists, exit immediately */
peer = ibss_rsn_get_peer(ibss_rsn, addr);
if (peer)
*/
peer->authentication_status |= IBSS_RSN_AUTH_BY_US;
return ibss_rsn_auth_init(ibss_rsn, peer);
+ } else {
+ os_get_reltime(&peer->own_auth_tx);
+ eloop_register_timeout(1, 0, ibss_rsn_auth_timeout, peer, NULL);
}
return 0;
ibss_rsn_free(prev);
}
- wpa_deinit(ibss_rsn->auth_group);
+ if (ibss_rsn->auth_group)
+ wpa_deinit(ibss_rsn->auth_group);
os_free(ibss_rsn);
}
if (peer &&
peer->authentication_status & IBSS_RSN_AUTH_EAPOL_BY_PEER) {
+ if (peer->own_auth_tx.sec) {
+ struct os_reltime now, diff;
+ os_get_reltime(&now);
+ os_reltime_sub(&now, &peer->own_auth_tx, &diff);
+ if (diff.sec == 0 && diff.usec < 500000) {
+ wpa_printf(MSG_DEBUG, "RSN: Skip IBSS reinit since only %u usec from own Auth frame TX",
+ (int) diff.usec);
+ goto skip_reinit;
+ }
+ }
/*
* A peer sent us an Authentication frame even though it already
* started an EAPOL session. We should reinit state machines
MAC2STR(addr));
}
+skip_reinit:
/* reply with an Authentication frame now, before sending an EAPOL */
ibss_rsn_send_auth(ibss_rsn, addr, 2);
/* no need to start another AUTH challenge in the other way.. */
}
/* authentication has been completed */
- wpa_printf(MSG_DEBUG, "RSN: IBSS Auth completed with "MACSTR,
+ eloop_cancel_timeout(ibss_rsn_auth_timeout, peer, NULL);
+ wpa_printf(MSG_DEBUG, "RSN: IBSS Auth completed with " MACSTR,
MAC2STR(header->sa));
ibss_rsn_peer_authenticated(ibss_rsn, peer,
IBSS_RSN_AUTH_BY_US);