示例#1
0
/*
 * Handle a station joining an RSN network.
 */
void
ieee80211_node_join_rsn(struct ieee80211com *ic, struct ieee80211_node *ni)
{
	DPRINTF(("station %s associated using proto %d akm 0x%x "
	    "cipher 0x%x groupcipher 0x%x\n", ether_sprintf(ni->ni_macaddr),
	    ni->ni_rsnprotos, ni->ni_rsnakms, ni->ni_rsnciphers,
	    ni->ni_rsngroupcipher));

	ni->ni_rsn_state = RSNA_AUTHENTICATION;
	ic->ic_rsnsta++;

	ni->ni_key_count = 0;
	ni->ni_port_valid = 0;
	ni->ni_flags &= ~IEEE80211_NODE_TXRXPROT;
	ni->ni_replaycnt = -1;	/* XXX */
	ni->ni_rsn_retries = 0;
	ni->ni_rsncipher = ni->ni_rsnciphers;

	ni->ni_rsn_state = RSNA_AUTHENTICATION_2;

	/* generate a new authenticator nonce (ANonce) */
	arc4random_buf(ni->ni_nonce, EAPOL_KEY_NONCE_LEN);

	if (!ieee80211_is_8021x_akm(ni->ni_rsnakms)) {
		memcpy(ni->ni_pmk, ic->ic_psk, IEEE80211_PMK_LEN);
		ni->ni_flags |= IEEE80211_NODE_PMK;
		(void)ieee80211_send_4way_msg1(ic, ni);
	} else if (ni->ni_flags & IEEE80211_NODE_PMK) {
		/* skip 802.1X auth if a cached PMK was found */
		(void)ieee80211_send_4way_msg1(ic, ni);
	} else {
		/* no cached PMK found, needs full 802.1X auth */
		ieee80211_needs_auth(ic, ni);
	}
}
/*
 * Handle EAPOL-Key timeouts (no answer from supplicant).
 */
void
ieee80211_eapol_timeout(void *arg)
{
	struct ieee80211_node *ni = arg;
	struct ieee80211com *ic = ni->ni_ic;
	int s;

	DPRINTF(("no answer from station %s in state %d\n",
	    ether_sprintf(ni->ni_macaddr), ni->ni_rsn_state));

	s = splnet();

	switch (ni->ni_rsn_state) {
	case RSNA_PTKSTART:
	case RSNA_PTKCALCNEGOTIATING:
		(void)ieee80211_send_4way_msg1(ic, ni);
		break;
	case RSNA_PTKINITNEGOTIATING:
		(void)ieee80211_send_4way_msg3(ic, ni);
		break;
	}

	switch (ni->ni_rsn_gstate) {
	case RSNA_REKEYNEGOTIATING:
		(void)ieee80211_send_group_msg1(ic, ni);
		break;
	}

	splx(s);
}