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) return 0; peer = ibss_rsn_peer_init(ibss_rsn, addr); if (peer == NULL) return -1; /* Open Authentication: send first Authentication frame */ res = ibss_rsn_send_auth(ibss_rsn, addr, 1); if (res) { /* * The driver may not support Authentication frame exchange in * IBSS. Ignore authentication and go through EAPOL exchange. */ 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; }
static void ibss_rsn_handle_auth_1_of_2(struct ibss_rsn *ibss_rsn, struct ibss_rsn_peer *peer, const u8* addr) { wpa_printf(MSG_DEBUG, "RSN: IBSS RX Auth frame (SEQ 1) from " MACSTR, MAC2STR(addr)); if (peer && peer->authentication_status & (IBSS_RSN_SET_PTK_SUPP | IBSS_RSN_SET_PTK_AUTH)) { /* Clear the TK for this pair to allow recovery from the case * where the peer STA has restarted and lost its key while we * still have a pairwise key configured. */ wpa_printf(MSG_DEBUG, "RSN: Clear pairwise key for peer " MACSTR, MAC2STR(addr)); wpa_drv_set_key(ibss_rsn->wpa_s, WPA_ALG_NONE, addr, 0, 0, NULL, 0, NULL, 0); } 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 * here, but it's much more complicated than just deleting and * recreating the state machine */ wpa_printf(MSG_DEBUG, "RSN: IBSS Reinitializing station " MACSTR, MAC2STR(addr)); ibss_rsn_stop(ibss_rsn, addr); peer = NULL; } if (!peer) { peer = ibss_rsn_peer_init(ibss_rsn, addr); if (!peer) return; wpa_printf(MSG_DEBUG, "RSN: IBSS Auth started by peer " MACSTR, 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.. */ ibss_rsn_peer_authenticated(ibss_rsn, peer, IBSS_RSN_AUTH_EAPOL_BY_US); }
static void ibss_rsn_handle_auth_1_of_2(struct ibss_rsn *ibss_rsn, struct ibss_rsn_peer *peer, const u8* addr) { wpa_printf(MSG_DEBUG, "RSN: IBSS RX Auth frame (SEQ 1) from " MACSTR, MAC2STR(addr)); 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 * here, but it's much more complicated than just deleting and * recreating the state machine */ wpa_printf(MSG_DEBUG, "RSN: IBSS Reinitializing station " MACSTR, MAC2STR(addr)); ibss_rsn_stop(ibss_rsn, addr); peer = NULL; } if (!peer) { peer = ibss_rsn_peer_init(ibss_rsn, addr); if (!peer) return; wpa_printf(MSG_DEBUG, "RSN: IBSS Auth started by peer " MACSTR, 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.. */ ibss_rsn_peer_authenticated(ibss_rsn, peer, IBSS_RSN_AUTH_EAPOL_BY_US); }