161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/* 261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * Hotspot 2.0 AP ANQP processing 361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * Copyright (c) 2009, Atheros Communications, Inc. 4f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt * Copyright (c) 2011-2013, Qualcomm Atheros, Inc. 561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * 661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * See README for more details. 861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "includes.h" 1161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "common.h" 1361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "common/ieee802_11_defs.h" 1461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "hostapd.h" 1561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "ap_config.h" 16f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt#include "ap_drv_ops.h" 1761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "hs20.h" 1861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtu8 * hostapd_eid_hs20_indication(struct hostapd_data *hapd, u8 *eid) 2161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 22f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u8 conf; 2361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!hapd->conf->hs20) 2461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return eid; 2561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *eid++ = WLAN_EID_VENDOR_SPECIFIC; 26f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt *eid++ = 7; 2761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt WPA_PUT_BE24(eid, OUI_WFA); 2861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt eid += 3; 2961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *eid++ = HS20_INDICATION_OUI_TYPE; 30f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt conf = HS20_VERSION; /* Release Number */ 31f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt conf |= HS20_ANQP_DOMAIN_ID_PRESENT; 32f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (hapd->conf->disable_dgaf) 33f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt conf |= HS20_DGAF_DISABLED; 34f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt *eid++ = conf; 35f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt WPA_PUT_LE16(eid, hapd->conf->anqp_domain_id); 36f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt eid += 2; 37f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 3861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return eid; 3961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 40f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 41f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 42f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtu8 * hostapd_eid_osen(struct hostapd_data *hapd, u8 *eid) 43f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 44f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u8 *len; 45f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u16 capab; 46f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 47f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (!hapd->conf->osen) 48f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return eid; 49f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 50f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt *eid++ = WLAN_EID_VENDOR_SPECIFIC; 51f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt len = eid++; /* to be filled */ 52f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt WPA_PUT_BE24(eid, OUI_WFA); 53f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt eid += 3; 54f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt *eid++ = HS20_OSEN_OUI_TYPE; 55f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 56f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* Group Data Cipher Suite */ 57f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt RSN_SELECTOR_PUT(eid, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED); 58f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt eid += RSN_SELECTOR_LEN; 59f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 60f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* Pairwise Cipher Suite Count and List */ 61f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt WPA_PUT_LE16(eid, 1); 62f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt eid += 2; 63f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt RSN_SELECTOR_PUT(eid, RSN_CIPHER_SUITE_CCMP); 64f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt eid += RSN_SELECTOR_LEN; 65f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 66f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* AKM Suite Count and List */ 67f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt WPA_PUT_LE16(eid, 1); 68f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt eid += 2; 69f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt RSN_SELECTOR_PUT(eid, RSN_AUTH_KEY_MGMT_OSEN); 70f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt eid += RSN_SELECTOR_LEN; 71f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 72f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* RSN Capabilities */ 73f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt capab = 0; 74f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (hapd->conf->wmm_enabled) { 75f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* 4 PTKSA replay counters when using WMM */ 76f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt capab |= (RSN_NUM_REPLAY_COUNTERS_16 << 2); 77f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 78f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt#ifdef CONFIG_IEEE80211W 79f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (hapd->conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) { 80f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt capab |= WPA_CAPABILITY_MFPC; 81f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (hapd->conf->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED) 82f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt capab |= WPA_CAPABILITY_MFPR; 83f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 84f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 85f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt WPA_PUT_LE16(eid, capab); 86f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt eid += 2; 87f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 88f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt *len = eid - len - 1; 89f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 90f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return eid; 91f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 92f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 93f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 94f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtint hs20_send_wnm_notification(struct hostapd_data *hapd, const u8 *addr, 95f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u8 osu_method, const char *url) 96f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 97f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct wpabuf *buf; 98f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt size_t len = 0; 99f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt int ret; 100f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 101f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* TODO: should refuse to send notification if the STA is not associated 102f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt * or if the STA did not indicate support for WNM-Notification */ 103f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 104f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (url) { 105f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt len = 1 + os_strlen(url); 106f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (5 + len > 255) { 107f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_INFO, "HS 2.0: Too long URL for " 108f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "WNM-Notification: '%s'", url); 109f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return -1; 110f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 111f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 112f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 113f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt buf = wpabuf_alloc(4 + 7 + len); 114f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (buf == NULL) 115f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return -1; 116f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 117f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_u8(buf, WLAN_ACTION_WNM); 118f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_u8(buf, WNM_NOTIFICATION_REQ); 119f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_u8(buf, 1); /* Dialog token */ 120f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_u8(buf, 1); /* Type - 1 reserved for WFA */ 121f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 122f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* Subscription Remediation subelement */ 123f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC); 124f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_u8(buf, 5 + len); 125f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_be24(buf, OUI_WFA); 126f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_u8(buf, HS20_WNM_SUB_REM_NEEDED); 127f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (url) { 128f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_u8(buf, len - 1); 129f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_data(buf, url, len - 1); 130f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_u8(buf, osu_method); 131f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } else { 132f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* Server URL and Server Method fields not included */ 133f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_u8(buf, 0); 134f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 135f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 136f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt ret = hostapd_drv_send_action(hapd, hapd->iface->freq, 0, addr, 137f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_head(buf), wpabuf_len(buf)); 138f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 139f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_free(buf); 140f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 141f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return ret; 142f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 143f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 144f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 145f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtint hs20_send_wnm_notification_deauth_req(struct hostapd_data *hapd, 146f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt const u8 *addr, 147f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt const struct wpabuf *payload) 148f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 149f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct wpabuf *buf; 150f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt int ret; 151f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 152f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* TODO: should refuse to send notification if the STA is not associated 153f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt * or if the STA did not indicate support for WNM-Notification */ 154f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 155f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt buf = wpabuf_alloc(4 + 6 + wpabuf_len(payload)); 156f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (buf == NULL) 157f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return -1; 158f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 159f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_u8(buf, WLAN_ACTION_WNM); 160f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_u8(buf, WNM_NOTIFICATION_REQ); 161f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_u8(buf, 1); /* Dialog token */ 162f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_u8(buf, 1); /* Type - 1 reserved for WFA */ 163f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 164f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* Deauthentication Imminent Notice subelement */ 165f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC); 166f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_u8(buf, 4 + wpabuf_len(payload)); 167f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_be24(buf, OUI_WFA); 168f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_u8(buf, HS20_WNM_DEAUTH_IMMINENT_NOTICE); 169f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_buf(buf, payload); 170f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 171f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt ret = hostapd_drv_send_action(hapd, hapd->iface->freq, 0, addr, 172f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_head(buf), wpabuf_len(buf)); 173f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 174f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_free(buf); 175f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 176f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return ret; 177f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 178