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, | void handle_probe_req(struct hostapd_data *hapd, | ||||||
| 		      const struct ieee80211_mgmt *mgmt, size_t len) | 		      const struct ieee80211_mgmt *mgmt, size_t len) | ||||||
| { | { | ||||||
| 	struct ieee80211_mgmt *resp; | 	u8 *resp; | ||||||
| 	struct ieee802_11_elems elems; | 	struct ieee802_11_elems elems; | ||||||
| 	char *ssid; |  | ||||||
| 	u8 *pos, *epos; |  | ||||||
| 	const u8 *ie; | 	const u8 *ie; | ||||||
| 	size_t ssid_len, ie_len; | 	size_t ie_len; | ||||||
| 	struct sta_info *sta = NULL; | 	struct sta_info *sta = NULL; | ||||||
| 	size_t buflen; | 	size_t i, resp_len; | ||||||
| 	size_t i; |  | ||||||
| 	int noack; | 	int noack; | ||||||
| 
 | 
 | ||||||
| 	ie = mgmt->u.probe_req.variable; | 	ie = mgmt->u.probe_req.variable; | ||||||
|  | @ -220,9 +323,6 @@ void handle_probe_req(struct hostapd_data *hapd, | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ssid = NULL; |  | ||||||
| 	ssid_len = 0; |  | ||||||
| 
 |  | ||||||
| 	if ((!elems.ssid || !elems.supp_rates)) { | 	if ((!elems.ssid || !elems.supp_rates)) { | ||||||
| 		wpa_printf(MSG_DEBUG, "STA " MACSTR " sent probe request " | 		wpa_printf(MSG_DEBUG, "STA " MACSTR " sent probe request " | ||||||
| 			   "without SSID or supported rates element", | 			   "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 && | 	    (elems.ssid_len == hapd->conf->ssid.ssid_len && | ||||||
| 	     os_memcmp(elems.ssid, hapd->conf->ssid.ssid, elems.ssid_len) == | 	     os_memcmp(elems.ssid, hapd->conf->ssid.ssid, elems.ssid_len) == | ||||||
| 	     0)) { | 	     0)) { | ||||||
| 		ssid = hapd->conf->ssid.ssid; |  | ||||||
| 		ssid_len = hapd->conf->ssid.ssid_len; |  | ||||||
| 		if (sta) | 		if (sta) | ||||||
| 			sta->ssid_probe = &hapd->conf->ssid; | 			sta->ssid_probe = &hapd->conf->ssid; | ||||||
| 	} | 	} else { | ||||||
| 
 |  | ||||||
| 	if (!ssid) { |  | ||||||
| 		if (!(mgmt->da[0] & 0x01)) { | 		if (!(mgmt->da[0] & 0x01)) { | ||||||
| 			char ssid_txt[33]; | 			char ssid_txt[33]; | ||||||
| 			ieee802_11_print_ssid(ssid_txt, elems.ssid, | 			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
 | 	/* TODO: verify that supp_rates contains at least one matching rate
 | ||||||
| 	 * with AP configuration */ | 	 * with AP configuration */ | ||||||
| #define MAX_PROBERESP_LEN 768 | 
 | ||||||
| 	buflen = MAX_PROBERESP_LEN; | 	resp = hostapd_gen_probe_resp(hapd, sta, mgmt, elems.p2p != NULL, | ||||||
| #ifdef CONFIG_WPS | 				      &resp_len); | ||||||
| 	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) | 	if (resp == NULL) | ||||||
| 		return; | 		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 | 	 * 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)); | 	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"); | 		perror("handle_probe_req: send"); | ||||||
| 
 | 
 | ||||||
| 	os_free(resp); | 	os_free(resp); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Arik Nemtsov
						Arik Nemtsov