Split Probe Response generation into a separate function
This is needed for Probe Response template, so move the code into a separate function that can be shared. Signed-hostap: Arik Nemtsov <arik@wizery.com> Signed-off-by: Arik Nemtsov <arik@wizery.com>
This commit is contained in:
		
							parent
							
								
									4f73d88afa
								
							
						
					
					
						commit
						eacc6b2478
					
				
					 1 changed files with 114 additions and 102 deletions
				
			
		
							
								
								
									
										216
									
								
								src/ap/beacon.c
									
									
									
									
									
								
							
							
						
						
									
										216
									
								
								src/ap/beacon.c
									
									
									
									
									
								
							|  | @ -186,18 +186,121 @@ static u8 * hostapd_eid_wpa(struct hostapd_data *hapd, u8 *eid, size_t len) | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, | ||||
| 				   struct sta_info *sta, | ||||
| 				   const struct ieee80211_mgmt *req, | ||||
| 				   int is_p2p, size_t *resp_len) | ||||
| { | ||||
| 	struct ieee80211_mgmt *resp; | ||||
| 	u8 *pos, *epos; | ||||
| 	size_t buflen; | ||||
| 
 | ||||
| #define MAX_PROBERESP_LEN 768 | ||||
| 	buflen = MAX_PROBERESP_LEN; | ||||
| #ifdef CONFIG_WPS | ||||
| 	if (hapd->wps_probe_resp_ie) | ||||
| 		buflen += wpabuf_len(hapd->wps_probe_resp_ie); | ||||
| #endif /* CONFIG_WPS */ | ||||
| #ifdef CONFIG_P2P | ||||
| 	if (hapd->p2p_probe_resp_ie) | ||||
| 		buflen += wpabuf_len(hapd->p2p_probe_resp_ie); | ||||
| #endif /* CONFIG_P2P */ | ||||
| 	resp = os_zalloc(buflen); | ||||
| 	if (resp == NULL) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	epos = ((u8 *) resp) + MAX_PROBERESP_LEN; | ||||
| 
 | ||||
| 	resp->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, | ||||
| 					   WLAN_FC_STYPE_PROBE_RESP); | ||||
| 	if (req) | ||||
| 		os_memcpy(resp->da, req->sa, ETH_ALEN); | ||||
| 	os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN); | ||||
| 
 | ||||
| 	os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN); | ||||
| 	resp->u.probe_resp.beacon_int = | ||||
| 		host_to_le16(hapd->iconf->beacon_int); | ||||
| 
 | ||||
| 	/* hardware or low-level driver will setup seq_ctrl and timestamp */ | ||||
| 	resp->u.probe_resp.capab_info = | ||||
| 		host_to_le16(hostapd_own_capab_info(hapd, sta, 1)); | ||||
| 
 | ||||
| 	pos = resp->u.probe_resp.variable; | ||||
| 	*pos++ = WLAN_EID_SSID; | ||||
| 	*pos++ = hapd->conf->ssid.ssid_len; | ||||
| 	os_memcpy(pos, hapd->conf->ssid.ssid, hapd->conf->ssid.ssid_len); | ||||
| 	pos += hapd->conf->ssid.ssid_len; | ||||
| 
 | ||||
| 	/* Supported rates */ | ||||
| 	pos = hostapd_eid_supp_rates(hapd, pos); | ||||
| 
 | ||||
| 	/* DS Params */ | ||||
| 	pos = hostapd_eid_ds_params(hapd, pos); | ||||
| 
 | ||||
| 	pos = hostapd_eid_country(hapd, pos, epos - pos); | ||||
| 
 | ||||
| 	/* ERP Information element */ | ||||
| 	pos = hostapd_eid_erp_info(hapd, pos); | ||||
| 
 | ||||
| 	/* Extended supported rates */ | ||||
| 	pos = hostapd_eid_ext_supp_rates(hapd, pos); | ||||
| 
 | ||||
| 	/* RSN, MDIE, WPA */ | ||||
| 	pos = hostapd_eid_wpa(hapd, pos, epos - pos); | ||||
| 
 | ||||
| #ifdef CONFIG_IEEE80211N | ||||
| 	pos = hostapd_eid_ht_capabilities(hapd, pos); | ||||
| 	pos = hostapd_eid_ht_operation(hapd, pos); | ||||
| #endif /* CONFIG_IEEE80211N */ | ||||
| 
 | ||||
| 	pos = hostapd_eid_ext_capab(hapd, pos); | ||||
| 
 | ||||
| 	pos = hostapd_eid_time_adv(hapd, pos); | ||||
| 	pos = hostapd_eid_time_zone(hapd, pos); | ||||
| 
 | ||||
| 	pos = hostapd_eid_interworking(hapd, pos); | ||||
| 	pos = hostapd_eid_adv_proto(hapd, pos); | ||||
| 	pos = hostapd_eid_roaming_consortium(hapd, pos); | ||||
| 
 | ||||
| 	/* Wi-Fi Alliance WMM */ | ||||
| 	pos = hostapd_eid_wmm(hapd, pos); | ||||
| 
 | ||||
| #ifdef CONFIG_WPS | ||||
| 	if (hapd->conf->wps_state && hapd->wps_probe_resp_ie) { | ||||
| 		os_memcpy(pos, wpabuf_head(hapd->wps_probe_resp_ie), | ||||
| 			  wpabuf_len(hapd->wps_probe_resp_ie)); | ||||
| 		pos += wpabuf_len(hapd->wps_probe_resp_ie); | ||||
| 	} | ||||
| #endif /* CONFIG_WPS */ | ||||
| 
 | ||||
| #ifdef CONFIG_P2P | ||||
| 	if ((hapd->conf->p2p & P2P_ENABLED) && is_p2p && | ||||
| 	    hapd->p2p_probe_resp_ie) { | ||||
| 		os_memcpy(pos, wpabuf_head(hapd->p2p_probe_resp_ie), | ||||
| 			  wpabuf_len(hapd->p2p_probe_resp_ie)); | ||||
| 		pos += wpabuf_len(hapd->p2p_probe_resp_ie); | ||||
| 	} | ||||
| #endif /* CONFIG_P2P */ | ||||
| #ifdef CONFIG_P2P_MANAGER | ||||
| 	if ((hapd->conf->p2p & (P2P_MANAGE | P2P_ENABLED | P2P_GROUP_OWNER)) == | ||||
| 	    P2P_MANAGE) | ||||
| 		pos = hostapd_eid_p2p_manage(hapd, pos); | ||||
| #endif /* CONFIG_P2P_MANAGER */ | ||||
| 
 | ||||
| 	*resp_len = pos - (u8 *) resp; | ||||
| 	return (u8 *) resp; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void handle_probe_req(struct hostapd_data *hapd, | ||||
| 		      const struct ieee80211_mgmt *mgmt, size_t len) | ||||
| { | ||||
| 	struct ieee80211_mgmt *resp; | ||||
| 	u8 *resp; | ||||
| 	struct ieee802_11_elems elems; | ||||
| 	char *ssid; | ||||
| 	u8 *pos, *epos; | ||||
| 	const u8 *ie; | ||||
| 	size_t ssid_len, ie_len; | ||||
| 	size_t ie_len; | ||||
| 	struct sta_info *sta = NULL; | ||||
| 	size_t buflen; | ||||
| 	size_t i; | ||||
| 	size_t i, resp_len; | ||||
| 	int noack; | ||||
| 
 | ||||
| 	ie = mgmt->u.probe_req.variable; | ||||
|  | @ -220,9 +323,6 @@ void handle_probe_req(struct hostapd_data *hapd, | |||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	ssid = NULL; | ||||
| 	ssid_len = 0; | ||||
| 
 | ||||
| 	if ((!elems.ssid || !elems.supp_rates)) { | ||||
| 		wpa_printf(MSG_DEBUG, "STA " MACSTR " sent probe request " | ||||
| 			   "without SSID or supported rates element", | ||||
|  | @ -267,13 +367,9 @@ void handle_probe_req(struct hostapd_data *hapd, | |||
| 	    (elems.ssid_len == hapd->conf->ssid.ssid_len && | ||||
| 	     os_memcmp(elems.ssid, hapd->conf->ssid.ssid, elems.ssid_len) == | ||||
| 	     0)) { | ||||
| 		ssid = hapd->conf->ssid.ssid; | ||||
| 		ssid_len = hapd->conf->ssid.ssid_len; | ||||
| 		if (sta) | ||||
| 			sta->ssid_probe = &hapd->conf->ssid; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!ssid) { | ||||
| 	} else { | ||||
| 		if (!(mgmt->da[0] & 0x01)) { | ||||
| 			char ssid_txt[33]; | ||||
| 			ieee802_11_print_ssid(ssid_txt, elems.ssid, | ||||
|  | @ -318,95 +414,11 @@ void handle_probe_req(struct hostapd_data *hapd, | |||
| 
 | ||||
| 	/* TODO: verify that supp_rates contains at least one matching rate
 | ||||
| 	 * with AP configuration */ | ||||
| #define MAX_PROBERESP_LEN 768 | ||||
| 	buflen = MAX_PROBERESP_LEN; | ||||
| #ifdef CONFIG_WPS | ||||
| 	if (hapd->wps_probe_resp_ie) | ||||
| 		buflen += wpabuf_len(hapd->wps_probe_resp_ie); | ||||
| #endif /* CONFIG_WPS */ | ||||
| #ifdef CONFIG_P2P | ||||
| 	if (hapd->p2p_probe_resp_ie) | ||||
| 		buflen += wpabuf_len(hapd->p2p_probe_resp_ie); | ||||
| #endif /* CONFIG_P2P */ | ||||
| 	resp = os_zalloc(buflen); | ||||
| 
 | ||||
| 	resp = hostapd_gen_probe_resp(hapd, sta, mgmt, elems.p2p != NULL, | ||||
| 				      &resp_len); | ||||
| 	if (resp == NULL) | ||||
| 		return; | ||||
| 	epos = ((u8 *) resp) + MAX_PROBERESP_LEN; | ||||
| 
 | ||||
| 	resp->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, | ||||
| 					   WLAN_FC_STYPE_PROBE_RESP); | ||||
| 	os_memcpy(resp->da, mgmt->sa, ETH_ALEN); | ||||
| 	os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN); | ||||
| 
 | ||||
| 	os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN); | ||||
| 	resp->u.probe_resp.beacon_int = | ||||
| 		host_to_le16(hapd->iconf->beacon_int); | ||||
| 
 | ||||
| 	/* hardware or low-level driver will setup seq_ctrl and timestamp */ | ||||
| 	resp->u.probe_resp.capab_info = | ||||
| 		host_to_le16(hostapd_own_capab_info(hapd, sta, 1)); | ||||
| 
 | ||||
| 	pos = resp->u.probe_resp.variable; | ||||
| 	*pos++ = WLAN_EID_SSID; | ||||
| 	*pos++ = ssid_len; | ||||
| 	os_memcpy(pos, ssid, ssid_len); | ||||
| 	pos += ssid_len; | ||||
| 
 | ||||
| 	/* Supported rates */ | ||||
| 	pos = hostapd_eid_supp_rates(hapd, pos); | ||||
| 
 | ||||
| 	/* DS Params */ | ||||
| 	pos = hostapd_eid_ds_params(hapd, pos); | ||||
| 
 | ||||
| 	pos = hostapd_eid_country(hapd, pos, epos - pos); | ||||
| 
 | ||||
| 	/* ERP Information element */ | ||||
| 	pos = hostapd_eid_erp_info(hapd, pos); | ||||
| 
 | ||||
| 	/* Extended supported rates */ | ||||
| 	pos = hostapd_eid_ext_supp_rates(hapd, pos); | ||||
| 
 | ||||
| 	/* RSN, MDIE, WPA */ | ||||
| 	pos = hostapd_eid_wpa(hapd, pos, epos - pos); | ||||
| 
 | ||||
| #ifdef CONFIG_IEEE80211N | ||||
| 	pos = hostapd_eid_ht_capabilities(hapd, pos); | ||||
| 	pos = hostapd_eid_ht_operation(hapd, pos); | ||||
| #endif /* CONFIG_IEEE80211N */ | ||||
| 
 | ||||
| 	pos = hostapd_eid_ext_capab(hapd, pos); | ||||
| 
 | ||||
| 	pos = hostapd_eid_time_adv(hapd, pos); | ||||
| 	pos = hostapd_eid_time_zone(hapd, pos); | ||||
| 
 | ||||
| 	pos = hostapd_eid_interworking(hapd, pos); | ||||
| 	pos = hostapd_eid_adv_proto(hapd, pos); | ||||
| 	pos = hostapd_eid_roaming_consortium(hapd, pos); | ||||
| 
 | ||||
| 	/* Wi-Fi Alliance WMM */ | ||||
| 	pos = hostapd_eid_wmm(hapd, pos); | ||||
| 
 | ||||
| #ifdef CONFIG_WPS | ||||
| 	if (hapd->conf->wps_state && hapd->wps_probe_resp_ie) { | ||||
| 		os_memcpy(pos, wpabuf_head(hapd->wps_probe_resp_ie), | ||||
| 			  wpabuf_len(hapd->wps_probe_resp_ie)); | ||||
| 		pos += wpabuf_len(hapd->wps_probe_resp_ie); | ||||
| 	} | ||||
| #endif /* CONFIG_WPS */ | ||||
| 
 | ||||
| #ifdef CONFIG_P2P | ||||
| 	if ((hapd->conf->p2p & P2P_ENABLED) && elems.p2p && | ||||
| 	    hapd->p2p_probe_resp_ie) { | ||||
| 		os_memcpy(pos, wpabuf_head(hapd->p2p_probe_resp_ie), | ||||
| 			  wpabuf_len(hapd->p2p_probe_resp_ie)); | ||||
| 		pos += wpabuf_len(hapd->p2p_probe_resp_ie); | ||||
| 	} | ||||
| #endif /* CONFIG_P2P */ | ||||
| #ifdef CONFIG_P2P_MANAGER | ||||
| 	if ((hapd->conf->p2p & (P2P_MANAGE | P2P_ENABLED | P2P_GROUP_OWNER)) == | ||||
| 	    P2P_MANAGE) | ||||
| 		pos = hostapd_eid_p2p_manage(hapd, pos); | ||||
| #endif /* CONFIG_P2P_MANAGER */ | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * If this is a broadcast probe request, apply no ack policy to avoid | ||||
|  | @ -414,7 +426,7 @@ void handle_probe_req(struct hostapd_data *hapd, | |||
| 	 */ | ||||
| 	noack = !!(elems.ssid_len == 0 && is_broadcast_ether_addr(mgmt->da)); | ||||
| 
 | ||||
| 	if (hostapd_drv_send_mlme(hapd, resp, pos - (u8 *) resp, noack) < 0) | ||||
| 	if (hostapd_drv_send_mlme(hapd, resp, resp_len, noack) < 0) | ||||
| 		perror("handle_probe_req: send"); | ||||
| 
 | ||||
| 	os_free(resp); | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Arik Nemtsov
						Arik Nemtsov