int wlan_mlme_auth_request(wlan_if_t vaphandle, u_int32_t timeout) { struct ieee80211vap *vap = vaphandle; struct ieee80211_mlme_priv *mlme_priv = vap->iv_mlme_priv; struct ieee80211_node *ni = vap->iv_bss; /* bss node */ int error = 0; IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s\n", __func__); /* wait for auth seq number 2 (open response or shared challenge) */ ASSERT(mlme_priv->im_request_type == MLME_REQ_NONE); mlme_priv->im_request_type = MLME_REQ_AUTH; mlme_priv->im_expected_auth_seq_number = IEEE80211_AUTH_OPEN_RESPONSE; /* Set the timeout timer for authenticate failure case */ OS_SET_TIMER(&mlme_priv->im_timeout_timer, timeout); /* Send the authentication packet */ error = ieee80211_send_auth(ni, IEEE80211_AUTH_SHARED_REQUEST, 0, NULL, 0); if (error) { goto err; } return error; err: mlme_priv->im_request_type = MLME_REQ_NONE; OS_CANCEL_TIMER(&mlme_priv->im_timeout_timer); return error; }
int ieee80211_mlme_auth_request_btamp(wlan_if_t vaphandle, u_int8_t *peer_addr, u_int32_t timeout) { struct ieee80211vap *vap = vaphandle; struct ieee80211_mlme_priv *mlme_priv = vap->iv_mlme_priv; struct ieee80211_node *ni = NULL; int error = 0; IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s\n", __func__); ni = ieee80211_find_txnode(vap, peer_addr); //ni = ieee80211_find_node(&vap->iv_ic->ic_sta, peer_addr); if (ni == NULL) { return EINVAL; } /* Wait for auth seq number 2 (open response) */ ASSERT(mlme_priv->im_request_type == MLME_REQ_NONE); mlme_priv->im_request_type = MLME_REQ_AUTH; mlme_priv->im_expected_auth_seq_number = IEEE80211_AUTH_OPEN_RESPONSE; /* Set the timeout timer for authenticate failure case */ OS_SET_TIMER(&mlme_priv->im_timeout_timer, timeout); /* Send the authentication packet */ error = ieee80211_send_auth(ni, IEEE80211_AUTH_OPEN_REQUEST, 0, NULL, 0); ieee80211_free_node(ni); if (error) { goto err; } return error; err: mlme_priv->im_request_type = MLME_REQ_NONE; OS_CANCEL_TIMER(&mlme_priv->im_timeout_timer); return error; }
int wlan_mlme_auth(wlan_if_t vaphandle, u_int8_t *macaddr, u_int16_t seq, u_int16_t status, u_int8_t *challenge_txt, u_int8_t challenge_len, struct ieee80211_app_ie_t* optie) { struct ieee80211vap *vap = vaphandle; struct ieee80211_node *ni; int error = 0; IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s status %d \n", __func__, status); ni = ieee80211_vap_find_node(vap, macaddr); if (ni == NULL) { error = -ENOMEM; return error; } /* Send auth frame */ if (status != IEEE80211_STATUS_SUCCESS) { ni->ni_authstatus = status; } ieee80211_send_auth(ni, seq, ni->ni_authstatus, challenge_txt, challenge_len, optie); if (ni->ni_authstatus != IEEE80211_STATUS_SUCCESS) { /* auth is not success, remove the node from node table */ IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s auth failed with status %d \n", __func__, ni->ni_authstatus); IEEE80211_NODE_LEAVE(ni); error = -EIO; } /* claim node immediately */ ieee80211_free_node(ni); return error; }
static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt, size_t len) { u16 auth_alg, auth_transaction; lockdep_assert_held(&sdata->u.ibss.mtx); if (len < 24 + 6) return; auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); /* * IEEE 802.11 standard does not require authentication in IBSS * networks and most implementations do not seem to use it. * However, try to reply to authentication attempts if someone * has actually implemented this. */ if (auth_alg == WLAN_AUTH_OPEN && auth_transaction == 1) ieee80211_send_auth(sdata, 2, WLAN_AUTH_OPEN, NULL, 0, sdata->u.ibss.bssid, NULL, 0, 0); }
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); }
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); } }