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