void mlme_recv_auth_sta(struct ieee80211_node *ni, u_int16_t algo, u_int16_t seq, u_int16_t status_code, u_int8_t *challenge, u_int8_t challenge_length, wbuf_t wbuf) { struct ieee80211vap *vap = ni->ni_vap; struct ieee80211_mlme_priv *mlme_priv = vap->iv_mlme_priv; IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s\n", __func__); if (mlme_priv->im_request_type != MLME_REQ_AUTH) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s: invalid request type\n", __func__, mlme_priv->im_request_type); return; } /* Validate algo */ if (algo == IEEE80211_AUTH_ALG_SHARED) { if (!RSN_AUTH_IS_SHARED_KEY(&vap->iv_rsn)) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s: Received a shared auth response in open mode.\n", __func__); } else { /* Mark node as shared key authentication */ RSN_RESET_AUTHMODE(&ni->ni_rsn); RSN_SET_AUTHMODE(&ni->ni_rsn, IEEE80211_AUTH_SHARED); } } /* Validate seq */ if (seq != mlme_priv->im_expected_auth_seq_number) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s: Invalid seq %d,%d\n", __func__, seq, mlme_priv->im_expected_auth_seq_number); return; } if (RSN_AUTH_IS_SHARED_KEY(&vap->iv_rsn) && (seq == IEEE80211_AUTH_SHARED_CHALLENGE) && (status_code == IEEE80211_STATUS_SUCCESS)) { /* Send the challenge response authentication packet. * We don't care if the send fails. If it does, the timeout routine will do * the necessary cleanup. */ ieee80211_send_auth(ni, seq + 1, 0, challenge, challenge_length); mlme_priv->im_expected_auth_seq_number = IEEE80211_AUTH_SHARED_PASS; return; } if (!OS_CANCEL_TIMER(&mlme_priv->im_timeout_timer)) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s: Timed-out already\n", __func__); return; } IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s: mlme_auth_complete\n", __func__); /* Request complete */ mlme_priv->im_request_type = MLME_REQ_NONE; /* Authentication complete (success or failure) */ IEEE80211_DELIVER_EVENT_MLME_AUTH_COMPLETE(vap, status_code); }
static void mlme_timeout_callback(struct ieee80211vap *vap, IEEE80211_STATUS ieeeStatus) { struct ieee80211_mlme_priv *mlme_priv = vap->iv_mlme_priv; int mlme_request_type = mlme_priv->im_request_type; IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s. Request type = %d\n", __func__, mlme_request_type); /* Request complete */ mlme_priv->im_request_type = MLME_REQ_NONE; switch(mlme_request_type) { case MLME_REQ_JOIN_INFRA: ASSERT(vap->iv_opmode != IEEE80211_M_IBSS); /* * Cancel the Join operation if it has not already completed */ if (MLME_STOP_WAITING_FOR_JOIN(mlme_priv) == TRUE) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME,"%s", "Cancelled the Join Operation as it took too long\n"); IEEE80211_DELIVER_EVENT_MLME_JOIN_COMPLETE_INFRA(vap, ieeeStatus); } break; case MLME_REQ_JOIN_ADHOC: ASSERT(vap->iv_opmode == IEEE80211_M_IBSS); /* * Cancel the Join operation if it has not already completed */ if (MLME_STOP_WAITING_FOR_JOIN(mlme_priv) == TRUE) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME,"%s", "Cancelled the Join Operation as it took too long\n"); IEEE80211_DELIVER_EVENT_MLME_JOIN_COMPLETE_ADHOC(vap, ieeeStatus); } break; case MLME_REQ_AUTH: /* * Cancel the auth operation if it has not already completed */ IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME,"%s", "Cancelled the Auth Operation as it took too long\n"); mlme_priv->im_expected_auth_seq_number = 0; IEEE80211_DELIVER_EVENT_MLME_AUTH_COMPLETE(vap, ieeeStatus); break; case MLME_REQ_ASSOC: /* * Cancel the assoc operation if it has not already completed */ IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME,"%s", "Cancelled the Assoc Operation as it took too long\n"); IEEE80211_DELIVER_EVENT_MLME_ASSOC_COMPLETE(vap, ieeeStatus, 0, NULL); break; case MLME_REQ_REASSOC: /* * Cancel the reassoc operation if it has not already completed */ IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME,"%s", "Cancelled the Reassoc Operation as it took too long\n"); IEEE80211_DELIVER_EVENT_MLME_REASSOC_COMPLETE(vap, ieeeStatus, 0, NULL); break; case MLME_REQ_NONE: IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME,"%s", "mlme_request_type is MLME_REQ_NONE, do nothing.\n"); break; default: ASSERT(0); break; } }
void mlme_recv_auth_btamp(struct ieee80211_node *ni, u_int16_t algo, u_int16_t seq, u_int16_t status_code, u_int8_t *challenge, u_int8_t challenge_length, wbuf_t wbuf) { struct ieee80211vap *vap = ni->ni_vap; struct ieee80211_mlme_priv *mlme_priv = vap->iv_mlme_priv; struct ieee80211_frame *wh; u_int16_t indication_status = IEEE80211_STATUS_SUCCESS,response_status = IEEE80211_STATUS_SUCCESS ; bool send_auth_response=true, indicate=true; wh = (struct ieee80211_frame *) wbuf_header(wbuf); /* AP must be up and running */ if (!mlme_priv->im_connection_up || ieee80211_vap_ready_is_clear(vap)) { return; } IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_AUTH, wh->i_addr2, "recv auth frame with algorithm %d seq %d \n", algo, seq); do { /* Check node existance for the peer */ if (ni == vap->iv_bss) { return; } else { ieee80211_ref_node(ni); } /* Validate algo */ if (algo == IEEE80211_AUTH_ALG_OPEN) { if (mlme_priv->im_expected_auth_seq_number) { send_auth_response = false; indicate = false; if (seq == mlme_priv->im_expected_auth_seq_number) { if (!OS_CANCEL_TIMER(&mlme_priv->im_timeout_timer)) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s: Timed-out already\n", __func__); break; } IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s: mlme_auth_complete\n", __func__); /* Request complete */ mlme_priv->im_request_type = MLME_REQ_NONE; /* Authentication complete (success or failure) */ IEEE80211_DELIVER_EVENT_MLME_AUTH_COMPLETE(vap, status_code); vap->iv_mlme_priv->im_expected_auth_seq_number = 0; } else { break; } } else { if (seq != IEEE80211_AUTH_OPEN_REQUEST) { response_status = IEEE80211_STATUS_SEQUENCE; indication_status = IEEE80211_STATUS_SEQUENCE; break; } else { indicate = true; send_auth_response = true; } } } else if (algo == IEEE80211_AUTH_ALG_SHARED) { response_status = IEEE80211_STATUS_ALG; indication_status = IEEE80211_STATUS_ALG; break; } else { IEEE80211_DPRINTF(vap, IEEE80211_MSG_AUTH | IEEE80211_MSG_CRYPTO, "[%s] auth: unsupported algorithm %d \n",ether_sprintf(wh->i_addr2),algo); vap->iv_stats.is_rx_auth_unsupported++; response_status = IEEE80211_STATUS_ALG; indication_status = IEEE80211_STATUS_ALG; break; } } while (FALSE); IEEE80211_DELIVER_EVENT_MLME_AUTH_INDICATION(vap, ni->ni_macaddr, indication_status); if (send_auth_response) { ieee80211_send_auth(ni, seq + 1, response_status, NULL, 0); } if (ni) { if (indication_status != IEEE80211_STATUS_SUCCESS ){ /* auth is not success, remove the node from node table*/ ieee80211_node_leave(ni); } /* * release the reference created at the begining of the case above * either by alloc_node or ref_node. */ ieee80211_free_node(ni); } }