⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ieee802_11.c

📁 hostapd源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
			size_t len){	u16 auth_alg, auth_transaction, status_code;	u16 resp = WLAN_STATUS_SUCCESS;	struct sta_info *sta = NULL;	int res;	u16 fc;	u8 *challenge = NULL;	u32 session_timeout, acct_interim_interval;	int vlan_id = 0;	if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {		printf("handle_auth - too short payload (len=%lu)\n",		       (unsigned long) len);		return;	}	auth_alg = le_to_host16(mgmt->u.auth.auth_alg);	auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);	status_code = le_to_host16(mgmt->u.auth.status_code);	fc = le_to_host16(mgmt->frame_control);	if (len >= IEEE80211_HDRLEN + sizeof(mgmt->u.auth) +	    2 + WLAN_AUTH_CHALLENGE_LEN &&	    mgmt->u.auth.variable[0] == WLAN_EID_CHALLENGE &&	    mgmt->u.auth.variable[1] == WLAN_AUTH_CHALLENGE_LEN)		challenge = &mgmt->u.auth.variable[2];	HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,		      "authentication: STA=" MACSTR " auth_alg=%d "		      "auth_transaction=%d status_code=%d wep=%d%s\n",		      MAC2STR(mgmt->sa), auth_alg, auth_transaction,		      status_code, !!(fc & WLAN_FC_ISWEP),		      challenge ? " challenge" : "");	if (hapd->assoc_ap_state == AUTHENTICATE && auth_transaction == 2 &&	    memcmp(mgmt->sa, hapd->conf->assoc_ap_addr, ETH_ALEN) == 0 &&	    memcmp(mgmt->bssid, hapd->conf->assoc_ap_addr, ETH_ALEN) == 0) {		if (status_code != 0) {			printf("Authentication (as station) with AP "			       MACSTR " failed (status_code=%d)\n",			       MAC2STR(hapd->conf->assoc_ap_addr),			       status_code);			return;		}		printf("Authenticated (as station) with AP " MACSTR "\n",		       MAC2STR(hapd->conf->assoc_ap_addr));		ieee802_11_sta_associate(hapd, NULL);		return;	}	if (hapd->tkip_countermeasures) {		resp = WLAN_REASON_MICHAEL_MIC_FAILURE;		goto fail;	}	if (!(((hapd->conf->auth_algs & HOSTAPD_AUTH_OPEN) &&	       auth_alg == WLAN_AUTH_OPEN) ||	      ((hapd->conf->auth_algs & HOSTAPD_AUTH_SHARED_KEY) &&	       auth_alg == WLAN_AUTH_SHARED_KEY))) {		printf("Unsupported authentication algorithm (%d)\n",		       auth_alg);		resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;		goto fail;	}	if (!(auth_transaction == 1 ||	      (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 3))) {		printf("Unknown authentication transaction number (%d)\n",		       auth_transaction);		resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;		goto fail;	}	if (memcmp(mgmt->sa, hapd->own_addr, ETH_ALEN) == 0) {		printf("Station " MACSTR " not allowed to authenticate.\n",		       MAC2STR(mgmt->sa));		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;		goto fail;	}	res = hostapd_allowed_address(hapd, mgmt->sa, (u8 *) mgmt, len,				      &session_timeout,				      &acct_interim_interval, &vlan_id);	if (res == HOSTAPD_ACL_REJECT) {		printf("Station " MACSTR " not allowed to authenticate.\n",		       MAC2STR(mgmt->sa));		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;		goto fail;	}	if (res == HOSTAPD_ACL_PENDING) {		HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "Authentication frame "			      "from " MACSTR " waiting for an external "			      "authentication\n", MAC2STR(mgmt->sa));		/* Authentication code will re-send the authentication frame		 * after it has received (and cached) information from the		 * external source. */		return;	}	sta = ap_sta_add(hapd, mgmt->sa);	if (!sta) {		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;		goto fail;	}	if (vlan_id > 0) {		sta->vlan_id = vlan_id;		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,			       HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id);	}	sta->flags &= ~WLAN_STA_PREAUTH;	ieee802_1x_notify_pre_auth(sta->eapol_sm, 0);	if (hapd->conf->radius->acct_interim_interval == 0 &&	    acct_interim_interval)		sta->acct_interim_interval = acct_interim_interval;	if (res == HOSTAPD_ACL_ACCEPT_TIMEOUT)		ap_sta_session_timeout(hapd, sta, session_timeout);	else		ap_sta_no_session_timeout(hapd, sta);	switch (auth_alg) {	case WLAN_AUTH_OPEN:		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,			       HOSTAPD_LEVEL_DEBUG,			       "authentication OK (open system)");#ifdef IEEE80211_REQUIRE_AUTH_ACK		/* Station will be marked authenticated if it ACKs the		 * authentication reply. */#else		sta->flags |= WLAN_STA_AUTH;		wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);#endif		break;	case WLAN_AUTH_SHARED_KEY:		resp = auth_shared_key(hapd, sta, auth_transaction, challenge,				       fc & WLAN_FC_ISWEP);		break;	} fail:	send_auth_reply(hapd, mgmt, auth_alg, auth_transaction + 1, resp,			sta ? sta->challenge : NULL);}static void handle_assoc(struct hostapd_data *hapd,			 struct ieee80211_mgmt *mgmt, size_t len, int reassoc){	u16 capab_info, listen_interval;	u16 resp = WLAN_STATUS_SUCCESS;	u8 *pos, *wpa_ie;	size_t wpa_ie_len;	int send_deauth = 0, send_len, left;	struct sta_info *sta;	struct ieee802_11_elems elems;	if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) :				      sizeof(mgmt->u.assoc_req))) {		printf("handle_assoc(reassoc=%d) - too short payload (len=%lu)"		       "\n", reassoc, (unsigned long) len);		return;	}	if (reassoc) {		capab_info = le_to_host16(mgmt->u.reassoc_req.capab_info);		listen_interval = le_to_host16(			mgmt->u.reassoc_req.listen_interval);		HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,			      "reassociation request: STA=" MACSTR			      " capab_info=0x%02x "			      "listen_interval=%d current_ap=" MACSTR "\n",			      MAC2STR(mgmt->sa), capab_info, listen_interval,			      MAC2STR(mgmt->u.reassoc_req.current_ap));		left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req));		pos = mgmt->u.reassoc_req.variable;	} else {		capab_info = le_to_host16(mgmt->u.assoc_req.capab_info);		listen_interval = le_to_host16(			mgmt->u.assoc_req.listen_interval);		HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,			      "association request: STA=" MACSTR			      " capab_info=0x%02x listen_interval=%d\n",			      MAC2STR(mgmt->sa), capab_info, listen_interval);		left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req));		pos = mgmt->u.assoc_req.variable;	}	sta = ap_get_sta(hapd, mgmt->sa);	if (sta == NULL || (sta->flags & WLAN_STA_AUTH) == 0) {		printf("STA " MACSTR " trying to associate before "		       "authentication\n", MAC2STR(mgmt->sa));		if (sta) {			printf("  sta: addr=" MACSTR " aid=%d flags=0x%04x\n",			       MAC2STR(sta->addr), sta->aid, sta->flags);		}		send_deauth = 1;		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;		goto fail;	}	if (hapd->tkip_countermeasures) {		resp = WLAN_REASON_MICHAEL_MIC_FAILURE;		goto fail;	}	sta->capability = capab_info;	/* followed by SSID and Supported rates */	if (ieee802_11_parse_elems(hapd, pos, left, &elems, 1) == ParseFailed	    || !elems.ssid) {		printf("STA " MACSTR " sent invalid association request\n",		       MAC2STR(sta->addr));		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;		goto fail;	}	if (elems.ssid_len != hapd->conf->ssid.ssid_len ||	    memcmp(elems.ssid, hapd->conf->ssid.ssid, elems.ssid_len) != 0) {		printf("Station " MACSTR " tried to associate with "		       "unknown SSID '", MAC2STR(sta->addr));		ieee802_11_print_ssid(elems.ssid, elems.ssid_len);		printf("'\n");		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;		goto fail;	}	if (!elems.supp_rates) {		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,			       HOSTAPD_LEVEL_DEBUG,			       "No supported rates element in AssocReq");		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;		goto fail;	}	if (elems.supp_rates_len > sizeof(sta->supported_rates)) {		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,			       HOSTAPD_LEVEL_DEBUG,			       "Invalid supported rates element length %d",			       elems.supp_rates_len);		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;		goto fail;	}	memset(sta->supported_rates, 0, sizeof(sta->supported_rates));	memcpy(sta->supported_rates, elems.supp_rates, elems.supp_rates_len);	sta->supported_rates_len = elems.supp_rates_len;	if (elems.ext_supp_rates) {		if (elems.supp_rates_len + elems.ext_supp_rates_len >		    sizeof(sta->supported_rates)) {			hostapd_logger(hapd, mgmt->sa,				       HOSTAPD_MODULE_IEEE80211,				       HOSTAPD_LEVEL_DEBUG,				       "Invalid supported rates element length"				       " %d+%d", elems.supp_rates_len,				       elems.ext_supp_rates_len);			resp = WLAN_STATUS_UNSPECIFIED_FAILURE;			goto fail;		}		memcpy(sta->supported_rates + elems.supp_rates_len,		       elems.ext_supp_rates, elems.ext_supp_rates_len);		sta->supported_rates_len += elems.ext_supp_rates_len;	}	if ((hapd->conf->wpa & HOSTAPD_WPA_VERSION_WPA2) && elems.rsn_ie) {		wpa_ie = elems.rsn_ie;		wpa_ie_len = elems.rsn_ie_len;	} else if ((hapd->conf->wpa & HOSTAPD_WPA_VERSION_WPA) &&		   elems.wpa_ie) {		wpa_ie = elems.wpa_ie;		wpa_ie_len = elems.wpa_ie_len;	} else {		wpa_ie = NULL;		wpa_ie_len = 0;	}	if (hapd->conf->wpa && wpa_ie == NULL) {		printf("STA " MACSTR ": No WPA/RSN IE in association "		       "request\n", MAC2STR(sta->addr));		resp = WLAN_STATUS_INVALID_IE;		goto fail;	}	if (hapd->conf->wpa) {		int res;		wpa_ie -= 2;		wpa_ie_len += 2;		if (sta->wpa_sm == NULL)			sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,							sta->addr);		if (sta->wpa_sm == NULL) {			printf("Failed to initialize WPA state machine\n");			resp = WLAN_STATUS_UNSPECIFIED_FAILURE;			goto fail;		}		res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,					  wpa_ie, wpa_ie_len);		if (res == WPA_INVALID_GROUP)			resp = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;		else if (res == WPA_INVALID_PAIRWISE)			resp = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;		else if (res == WPA_INVALID_AKMP)			resp = WLAN_STATUS_AKMP_NOT_VALID;		else if (res == WPA_ALLOC_FAIL)			resp = WLAN_STATUS_UNSPECIFIED_FAILURE;		else if (res != WPA_IE_OK)			resp = WLAN_STATUS_INVALID_IE;		if (resp != WLAN_STATUS_SUCCESS)			goto fail;	}	/* get a unique AID */	if (sta->aid > 0) {		HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,			      "  old AID %d\n", sta->aid);	} else {		for (sta->aid = 1; sta->aid <= MAX_AID_TABLE_SIZE; sta->aid++)			if (hapd->sta_aid[sta->aid - 1] == NULL)				break;		if (sta->aid > MAX_AID_TABLE_SIZE) {			sta->aid = 0;			resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;			printf("  no room for more AIDs\n");			goto fail;		} else {			hapd->sta_aid[sta->aid - 1] = sta;			HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,				      "  new AID %d\n", sta->aid);		}	}	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,		       HOSTAPD_LEVEL_DEBUG,		       "association OK (aid %d)", sta->aid);	/* Station will be marked associated, after it acknowledges AssocResp	 */	if (sta->last_assoc_req)		free(sta->last_assoc_req);	sta->last_assoc_req = (struct ieee80211_mgmt *) malloc(len);	if (sta->last_assoc_req)		memcpy(sta->last_assoc_req, mgmt, len);	/* Make sure that the previously registered inactivity timer will not	 * remove the STA immediately. */	sta->timeout_next = STA_NULLFUNC; fail:	/* use the queued buffer for transmission because it is large enough	 * and not needed anymore */	mgmt->frame_control =		IEEE80211_FC(WLAN_FC_TYPE_MGMT,			     (send_deauth ? WLAN_FC_STYPE_DEAUTH :			      (reassoc ? WLAN_FC_STYPE_REASSOC_RESP :			       WLAN_FC_STYPE_ASSOC_RESP)));	memcpy(mgmt->da, mgmt->sa, ETH_ALEN);	memcpy(mgmt->sa, hapd->own_addr, ETH_ALEN);	/* Addr3 = BSSID - already set */	send_len = IEEE80211_HDRLEN;	if (send_deauth) {		send_len += sizeof(mgmt->u.deauth);		mgmt->u.deauth.reason_code = host_to_le16(resp);	} else {		u8 *p;		send_len += sizeof(mgmt->u.assoc_resp);		mgmt->u.assoc_resp.capab_info =			host_to_le16(hostapd_own_capab_info(hapd, sta, 0));		mgmt->u.assoc_resp.status_code = host_to_le16(resp);		mgmt->u.assoc_resp.aid = host_to_le16((sta ? sta->aid : 0)						      | BIT(14) | BIT(15));		/* Supported rates */		p = hostapd_eid_supp_rates(hapd, mgmt->u.assoc_resp.variable);		/* Extended supported rates */		p = hostapd_eid_ext_supp_rates(hapd, p);		send_len += p - mgmt->u.assoc_resp.variable;		/* Request TX callback */		mgmt->frame_control |= host_to_le16(BIT(1));	}	if (hostapd_send_mgmt_frame(hapd, mgmt, send_len, 0) < 0)		perror("handle_assoc: send");}static void handle_assoc_resp(struct hostapd_data *hapd,			      struct ieee80211_mgmt *mgmt, size_t len){	u16 status_code, aid;	if (hapd->assoc_ap_state != ASSOCIATE) {		printf("Unexpected association response received from " MACSTR		       "\n", MAC2STR(mgmt->sa));		return;	}	if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_resp)) {		printf("handle_assoc_resp - too short payload (len=%lu)\n",		       (unsigned long) len);		return;	}	if (memcmp(mgmt->sa, hapd->conf->assoc_ap_addr, ETH_ALEN) != 0 ||	    memcmp(mgmt->bssid, hapd->conf->assoc_ap_addr, ETH_ALEN) != 0) {		printf("Received association response from unexpected address "		       "(SA=" MACSTR " BSSID=" MACSTR "\n",		       MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid));		return;	}	status_code = le_to_host16(mgmt->u.assoc_resp.status_code);	aid = le_to_host16(mgmt->u.assoc_resp.aid);	aid &= ~(BIT(14) | BIT(15));	if (status_code != 0) {		printf("Association (as station) with AP " MACSTR " failed "		       "(status_code=%d)\n",		       MAC2STR(hapd->conf->assoc_ap_addr), status_code);		/* Try to authenticate again */		hapd->assoc_ap_state = AUTHENTICATE;		eloop_register_timeout(5, 0, ieee802_11_sta_authenticate,				       hapd, NULL);	}	printf("Associated (as station) with AP " MACSTR " (aid=%d)\n",	       MAC2STR(hapd->conf->assoc_ap_addr), aid);	hapd->assoc_ap_aid = aid;	hapd->assoc_ap_state = ASSOCIATED;	if (hostapd_set_assoc_ap(hapd, hapd->conf->assoc_ap_addr)) {		printf("Could not set associated AP address to kernel "		       "driver.\n");	}}static void handle_disassoc(struct hostapd_data *hapd,			    struct ieee80211_mgmt *mgmt, size_t len){	struct sta_info *sta;	if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.disassoc)) {		printf("handle_disassoc - too short payload (len=%lu)\n",		       (unsigned long) len);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -