Browse Source

Add crypto parameters to set_ap() command separately

This helps drivers that build the Beacon and Probe Response frames
internally.
Jouni Malinen 13 years ago
parent
commit
b11d1d6439
3 changed files with 105 additions and 0 deletions
  1. 10 0
      src/ap/beacon.c
  2. 30 0
      src/drivers/driver.h
  3. 65 0
      src/drivers/driver_nl80211.c

+ 10 - 0
src/ap/beacon.c

@@ -520,6 +520,16 @@ void ieee802_11_set_beacon(struct hostapd_data *hapd)
 	params.beacon_int = hapd->iconf->beacon_int;
 	params.ssid = (u8 *) hapd->conf->ssid.ssid;
 	params.ssid_len = hapd->conf->ssid.ssid_len;
+	params.pairwise_ciphers = hapd->conf->rsn_pairwise ?
+		hapd->conf->rsn_pairwise : hapd->conf->wpa_pairwise;
+	params.group_cipher = hapd->conf->wpa_group;
+	params.key_mgmt_suites = hapd->conf->wpa_key_mgmt;
+	params.auth_algs = hapd->conf->auth_algs;
+	params.wpa_version = hapd->conf->wpa;
+	params.privacy = hapd->conf->ssid.wep.keys_set || hapd->conf->wpa ||
+		(hapd->conf->ieee802_1x &&
+		 (hapd->conf->default_wep_key_len ||
+		  hapd->conf->individual_wep_key_len));
 	if (hostapd_drv_set_ap(hapd, &params))
 		wpa_printf(MSG_ERROR, "Failed to set beacon parameters");
 

+ 30 - 0
src/drivers/driver.h

@@ -540,6 +540,36 @@ struct wpa_driver_ap_params {
 	 * ssid_len - Length of the SSID (1..32)
 	 */
 	size_t ssid_len;
+
+	/**
+	 * pairwise_ciphers - WPA_CIPHER_* bitfield
+	 */
+	unsigned int pairwise_ciphers;
+
+	/**
+	 * group_cipher - WPA_CIPHER_*
+	 */
+	unsigned int group_cipher;
+
+	/**
+	 * key_mgmt_suites - WPA_KEY_MGMT_* bitfield
+	 */
+	unsigned int key_mgmt_suites;
+
+	/**
+	 * auth_algs - WPA_AUTH_ALG_* bitfield
+	 */
+	unsigned int auth_algs;
+
+	/**
+	 * wpa_version - WPA_PROTO_* bitfield
+	 */
+	unsigned int wpa_version;
+
+	/**
+	 * privacy - Whether privacy is used in the BSS
+	 */
+	int privacy;
 };
 
 /**

+ 65 - 0
src/drivers/driver_nl80211.c

@@ -3828,6 +3828,9 @@ static int wpa_driver_nl80211_set_ap(void *priv,
 	int ret;
 	int beacon_set;
 	int ifindex = if_nametoindex(bss->ifname);
+	int num_suites;
+	u32 suites[10];
+	u32 ver;
 
 	beacon_set = bss->beacon_set;
 
@@ -3849,6 +3852,68 @@ static int wpa_driver_nl80211_set_ap(void *priv,
 	NLA_PUT_U32(msg, NL80211_ATTR_DTIM_PERIOD, params->dtim_period);
 	NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
 		params->ssid);
+	if (params->privacy)
+		NLA_PUT_FLAG(msg, NL80211_ATTR_PRIVACY);
+	if ((params->auth_algs & (WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED)) ==
+	    (WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED)) {
+		/* Leave out the attribute */
+	} else if (params->auth_algs & WPA_AUTH_ALG_SHARED)
+		NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE,
+			    NL80211_AUTHTYPE_SHARED_KEY);
+	else
+		NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE,
+			    NL80211_AUTHTYPE_OPEN_SYSTEM);
+
+	ver = 0;
+	if (params->wpa_version & WPA_PROTO_WPA)
+		ver |= NL80211_WPA_VERSION_1;
+	if (params->wpa_version & WPA_PROTO_RSN)
+		ver |= NL80211_WPA_VERSION_2;
+	if (ver)
+		NLA_PUT_U32(msg, NL80211_ATTR_WPA_VERSIONS, ver);
+
+	num_suites = 0;
+	if (params->key_mgmt_suites & WPA_KEY_MGMT_IEEE8021X)
+		suites[num_suites++] = WLAN_AKM_SUITE_8021X;
+	if (params->key_mgmt_suites & WPA_KEY_MGMT_PSK)
+		suites[num_suites++] = WLAN_AKM_SUITE_PSK;
+	if (num_suites) {
+		NLA_PUT(msg, NL80211_ATTR_AKM_SUITES,
+			num_suites * sizeof(u32), suites);
+	}
+
+	num_suites = 0;
+	if (params->pairwise_ciphers & WPA_CIPHER_CCMP)
+		suites[num_suites++] = WLAN_CIPHER_SUITE_CCMP;
+	if (params->pairwise_ciphers & WPA_CIPHER_TKIP)
+		suites[num_suites++] = WLAN_CIPHER_SUITE_TKIP;
+	if (params->pairwise_ciphers & WPA_CIPHER_WEP104)
+		suites[num_suites++] = WLAN_CIPHER_SUITE_WEP104;
+	if (params->pairwise_ciphers & WPA_CIPHER_WEP40)
+		suites[num_suites++] = WLAN_CIPHER_SUITE_WEP40;
+	if (num_suites) {
+		NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
+			num_suites * sizeof(u32), suites);
+	}
+
+	switch (params->group_cipher) {
+	case WPA_CIPHER_CCMP:
+		NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP,
+			    WLAN_CIPHER_SUITE_CCMP);
+		break;
+	case WPA_CIPHER_TKIP:
+		NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP,
+			    WLAN_CIPHER_SUITE_TKIP);
+		break;
+	case WPA_CIPHER_WEP104:
+		NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP,
+			    WLAN_CIPHER_SUITE_WEP104);
+		break;
+	case WPA_CIPHER_WEP40:
+		NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP,
+			    WLAN_CIPHER_SUITE_WEP40);
+		break;
+	}
 
 	ret = send_and_recv_msgs(drv, msg, NULL, NULL);
 	if (ret) {