$search
00001 /* 00002 * WPA Supplicant - Basic AP mode support routines 00003 * Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi> 00004 * Copyright (c) 2009, Atheros Communications 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License version 2 as 00008 * published by the Free Software Foundation. 00009 * 00010 * Alternatively, this software may be distributed under the terms of BSD 00011 * license. 00012 * 00013 * See README and COPYING for more details. 00014 */ 00015 00016 #include "utils/includes.h" 00017 00018 #include "utils/common.h" 00019 #include "common/ieee802_11_defs.h" 00020 #include "ap/hostapd.h" 00021 #include "ap/ap_config.h" 00022 #ifdef NEED_AP_MLME 00023 #include "ap/ieee802_11.h" 00024 #endif /* NEED_AP_MLME */ 00025 #include "ap/ieee802_1x.h" 00026 #include "ap/wps_hostapd.h" 00027 #include "ap/ctrl_iface_ap.h" 00028 #include "eap_common/eap_defs.h" 00029 #include "eap_server/eap_methods.h" 00030 #include "eap_common/eap_wsc_common.h" 00031 #include "wps/wps.h" 00032 #include "config_ssid.h" 00033 #include "config.h" 00034 #include "wpa_supplicant_i.h" 00035 #include "driver_i.h" 00036 #include "ap.h" 00037 00038 00039 static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s, 00040 struct wpa_ssid *ssid, 00041 struct hostapd_config *conf) 00042 { 00043 struct hostapd_bss_config *bss = &conf->bss[0]; 00044 int pairwise; 00045 00046 conf->driver = wpa_s->driver; 00047 00048 os_strlcpy(bss->iface, wpa_s->ifname, sizeof(bss->iface)); 00049 00050 if (ssid->frequency == 0) { 00051 /* default channel 11 */ 00052 conf->hw_mode = HOSTAPD_MODE_IEEE80211G; 00053 conf->channel = 11; 00054 } else if (ssid->frequency >= 2412 && ssid->frequency <= 2472) { 00055 conf->hw_mode = HOSTAPD_MODE_IEEE80211G; 00056 conf->channel = (ssid->frequency - 2407) / 5; 00057 } else if ((ssid->frequency >= 5180 && ssid->frequency <= 5240) || 00058 (ssid->frequency >= 5745 && ssid->frequency <= 5825)) { 00059 conf->hw_mode = HOSTAPD_MODE_IEEE80211A; 00060 conf->channel = (ssid->frequency - 5000) / 5; 00061 } else { 00062 wpa_printf(MSG_ERROR, "Unsupported AP mode frequency: %d MHz", 00063 ssid->frequency); 00064 return -1; 00065 } 00066 00067 /* TODO: enable HT if driver supports it; 00068 * drop to 11b if driver does not support 11g */ 00069 00070 if (ssid->ssid_len == 0) { 00071 wpa_printf(MSG_ERROR, "No SSID configured for AP mode"); 00072 return -1; 00073 } 00074 os_memcpy(bss->ssid.ssid, ssid->ssid, ssid->ssid_len); 00075 bss->ssid.ssid[ssid->ssid_len] = '\0'; 00076 bss->ssid.ssid_len = ssid->ssid_len; 00077 bss->ssid.ssid_set = 1; 00078 00079 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) 00080 bss->wpa = ssid->proto; 00081 bss->wpa_key_mgmt = ssid->key_mgmt; 00082 bss->wpa_pairwise = ssid->pairwise_cipher; 00083 if (ssid->passphrase) { 00084 bss->ssid.wpa_passphrase = os_strdup(ssid->passphrase); 00085 } else if (ssid->psk_set) { 00086 os_free(bss->ssid.wpa_psk); 00087 bss->ssid.wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk)); 00088 if (bss->ssid.wpa_psk == NULL) 00089 return -1; 00090 os_memcpy(bss->ssid.wpa_psk->psk, ssid->psk, PMK_LEN); 00091 bss->ssid.wpa_psk->group = 1; 00092 } 00093 00094 /* Select group cipher based on the enabled pairwise cipher suites */ 00095 pairwise = 0; 00096 if (bss->wpa & 1) 00097 pairwise |= bss->wpa_pairwise; 00098 if (bss->wpa & 2) { 00099 if (bss->rsn_pairwise == 0) 00100 bss->rsn_pairwise = bss->wpa_pairwise; 00101 pairwise |= bss->rsn_pairwise; 00102 } 00103 if (pairwise & WPA_CIPHER_TKIP) 00104 bss->wpa_group = WPA_CIPHER_TKIP; 00105 else 00106 bss->wpa_group = WPA_CIPHER_CCMP; 00107 00108 if (bss->wpa && bss->ieee802_1x) 00109 bss->ssid.security_policy = SECURITY_WPA; 00110 else if (bss->wpa) 00111 bss->ssid.security_policy = SECURITY_WPA_PSK; 00112 else if (bss->ieee802_1x) { 00113 bss->ssid.security_policy = SECURITY_IEEE_802_1X; 00114 bss->ssid.wep.default_len = bss->default_wep_key_len; 00115 } else if (bss->ssid.wep.keys_set) 00116 bss->ssid.security_policy = SECURITY_STATIC_WEP; 00117 else 00118 bss->ssid.security_policy = SECURITY_PLAINTEXT; 00119 00120 #ifdef CONFIG_WPS 00121 /* 00122 * Enable WPS by default, but require user interaction to actually use 00123 * it. Only the internal Registrar is supported. 00124 */ 00125 bss->eap_server = 1; 00126 bss->wps_state = 2; 00127 bss->ap_setup_locked = 1; 00128 if (wpa_s->conf->config_methods) 00129 bss->config_methods = os_strdup(wpa_s->conf->config_methods); 00130 if (wpa_s->conf->device_type) 00131 bss->device_type = os_strdup(wpa_s->conf->device_type); 00132 #endif /* CONFIG_WPS */ 00133 00134 return 0; 00135 } 00136 00137 00138 static void ap_public_action_rx(void *ctx, const u8 *buf, size_t len, int freq) 00139 { 00140 } 00141 00142 00143 static int ap_probe_req_rx(void *ctx, const u8 *addr, const u8 *ie, 00144 size_t ie_len) 00145 { 00146 return 0; 00147 } 00148 00149 00150 static void ap_wps_reg_success_cb(void *ctx, const u8 *mac_addr, 00151 const u8 *uuid_e) 00152 { 00153 } 00154 00155 00156 int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s, 00157 struct wpa_ssid *ssid) 00158 { 00159 struct wpa_driver_associate_params params; 00160 struct hostapd_iface *hapd_iface; 00161 struct hostapd_config *conf; 00162 size_t i; 00163 00164 if (ssid->ssid == NULL || ssid->ssid_len == 0) { 00165 wpa_printf(MSG_ERROR, "No SSID configured for AP mode"); 00166 return -1; 00167 } 00168 00169 wpa_supplicant_ap_deinit(wpa_s); 00170 00171 wpa_printf(MSG_DEBUG, "Setting up AP (SSID='%s')", 00172 wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); 00173 00174 os_memset(¶ms, 0, sizeof(params)); 00175 params.ssid = ssid->ssid; 00176 params.ssid_len = ssid->ssid_len; 00177 switch (ssid->mode) { 00178 case WPAS_MODE_INFRA: 00179 params.mode = IEEE80211_MODE_INFRA; 00180 break; 00181 case WPAS_MODE_IBSS: 00182 params.mode = IEEE80211_MODE_IBSS; 00183 break; 00184 case WPAS_MODE_AP: 00185 params.mode = IEEE80211_MODE_AP; 00186 break; 00187 } 00188 params.freq = ssid->frequency; 00189 00190 if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) 00191 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK; 00192 else 00193 wpa_s->key_mgmt = WPA_KEY_MGMT_NONE; 00194 params.key_mgmt_suite = key_mgmt2driver(wpa_s->key_mgmt); 00195 00196 if (ssid->pairwise_cipher & WPA_CIPHER_CCMP) 00197 wpa_s->pairwise_cipher = WPA_CIPHER_CCMP; 00198 else if (ssid->pairwise_cipher & WPA_CIPHER_TKIP) 00199 wpa_s->pairwise_cipher = WPA_CIPHER_TKIP; 00200 else if (ssid->pairwise_cipher & WPA_CIPHER_NONE) 00201 wpa_s->pairwise_cipher = WPA_CIPHER_NONE; 00202 else { 00203 wpa_printf(MSG_WARNING, "WPA: Failed to select pairwise " 00204 "cipher."); 00205 return -1; 00206 } 00207 params.pairwise_suite = cipher_suite2driver(wpa_s->pairwise_cipher); 00208 params.group_suite = params.pairwise_suite; 00209 00210 if (wpa_drv_associate(wpa_s, ¶ms) < 0) { 00211 wpa_msg(wpa_s, MSG_INFO, "Failed to start AP functionality"); 00212 return -1; 00213 } 00214 00215 wpa_s->ap_iface = hapd_iface = os_zalloc(sizeof(*wpa_s->ap_iface)); 00216 if (hapd_iface == NULL) 00217 return -1; 00218 hapd_iface->owner = wpa_s; 00219 00220 wpa_s->ap_iface->conf = conf = hostapd_config_defaults(); 00221 if (conf == NULL) { 00222 wpa_supplicant_ap_deinit(wpa_s); 00223 return -1; 00224 } 00225 00226 if (wpa_supplicant_conf_ap(wpa_s, ssid, conf)) { 00227 wpa_printf(MSG_ERROR, "Failed to create AP configuration"); 00228 wpa_supplicant_ap_deinit(wpa_s); 00229 return -1; 00230 } 00231 00232 hapd_iface->num_bss = conf->num_bss; 00233 hapd_iface->bss = os_zalloc(conf->num_bss * 00234 sizeof(struct hostapd_data *)); 00235 if (hapd_iface->bss == NULL) { 00236 wpa_supplicant_ap_deinit(wpa_s); 00237 return -1; 00238 } 00239 00240 for (i = 0; i < conf->num_bss; i++) { 00241 hapd_iface->bss[i] = 00242 hostapd_alloc_bss_data(hapd_iface, conf, 00243 &conf->bss[i]); 00244 if (hapd_iface->bss[i] == NULL) { 00245 wpa_supplicant_ap_deinit(wpa_s); 00246 return -1; 00247 } 00248 00249 hapd_iface->bss[i]->msg_ctx = wpa_s; 00250 hapd_iface->bss[i]->public_action_cb = ap_public_action_rx; 00251 hapd_iface->bss[i]->public_action_cb_ctx = wpa_s; 00252 hostapd_register_probereq_cb(hapd_iface->bss[i], 00253 ap_probe_req_rx, wpa_s); 00254 hapd_iface->bss[i]->wps_reg_success_cb = ap_wps_reg_success_cb; 00255 hapd_iface->bss[i]->wps_reg_success_cb_ctx = wpa_s; 00256 } 00257 00258 os_memcpy(hapd_iface->bss[0]->own_addr, wpa_s->own_addr, ETH_ALEN); 00259 hapd_iface->bss[0]->driver = wpa_s->driver; 00260 hapd_iface->bss[0]->drv_priv = wpa_s->drv_priv; 00261 00262 if (hostapd_setup_interface(wpa_s->ap_iface)) { 00263 wpa_printf(MSG_ERROR, "Failed to initialize AP interface"); 00264 wpa_supplicant_ap_deinit(wpa_s); 00265 return -1; 00266 } 00267 00268 wpa_s->current_ssid = ssid; 00269 os_memcpy(wpa_s->bssid, wpa_s->own_addr, ETH_ALEN); 00270 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); 00271 00272 if (wpa_s->ap_configured_cb) 00273 wpa_s->ap_configured_cb(wpa_s->ap_configured_cb_ctx, 00274 wpa_s->ap_configured_cb_data); 00275 00276 return 0; 00277 } 00278 00279 00280 void wpa_supplicant_ap_deinit(struct wpa_supplicant *wpa_s) 00281 { 00282 if (wpa_s->ap_iface == NULL) 00283 return; 00284 00285 wpa_s->current_ssid = NULL; 00286 hostapd_interface_deinit(wpa_s->ap_iface); 00287 hostapd_interface_free(wpa_s->ap_iface); 00288 wpa_s->ap_iface = NULL; 00289 wpa_drv_deinit_ap(wpa_s); 00290 } 00291 00292 00293 void ap_tx_status(void *ctx, const u8 *addr, 00294 const u8 *buf, size_t len, int ack) 00295 { 00296 #ifdef NEED_AP_MLME 00297 struct wpa_supplicant *wpa_s = ctx; 00298 hostapd_tx_status(wpa_s->ap_iface->bss[0], addr, buf, len, ack); 00299 #endif /* NEED_AP_MLME */ 00300 } 00301 00302 00303 void ap_rx_from_unknown_sta(void *ctx, const u8 *frame, size_t len) 00304 { 00305 #ifdef NEED_AP_MLME 00306 struct wpa_supplicant *wpa_s = ctx; 00307 const struct ieee80211_hdr *hdr = 00308 (const struct ieee80211_hdr *) frame; 00309 u16 fc = le_to_host16(hdr->frame_control); 00310 ieee802_11_rx_from_unknown(wpa_s->ap_iface->bss[0], hdr->addr2, 00311 (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == 00312 (WLAN_FC_TODS | WLAN_FC_FROMDS)); 00313 #endif /* NEED_AP_MLME */ 00314 } 00315 00316 00317 void ap_mgmt_rx(void *ctx, struct rx_mgmt *rx_mgmt) 00318 { 00319 #ifdef NEED_AP_MLME 00320 struct wpa_supplicant *wpa_s = ctx; 00321 struct hostapd_frame_info fi; 00322 os_memset(&fi, 0, sizeof(fi)); 00323 fi.datarate = rx_mgmt->datarate; 00324 fi.ssi_signal = rx_mgmt->ssi_signal; 00325 ieee802_11_mgmt(wpa_s->ap_iface->bss[0], rx_mgmt->frame, 00326 rx_mgmt->frame_len, &fi); 00327 #endif /* NEED_AP_MLME */ 00328 } 00329 00330 00331 void ap_mgmt_tx_cb(void *ctx, const u8 *buf, size_t len, u16 stype, int ok) 00332 { 00333 #ifdef NEED_AP_MLME 00334 struct wpa_supplicant *wpa_s = ctx; 00335 ieee802_11_mgmt_cb(wpa_s->ap_iface->bss[0], buf, len, stype, ok); 00336 #endif /* NEED_AP_MLME */ 00337 } 00338 00339 00340 void wpa_supplicant_ap_rx_eapol(struct wpa_supplicant *wpa_s, 00341 const u8 *src_addr, const u8 *buf, size_t len) 00342 { 00343 ieee802_1x_receive(wpa_s->ap_iface->bss[0], src_addr, buf, len); 00344 } 00345 00346 00347 #ifdef CONFIG_WPS 00348 00349 int wpa_supplicant_ap_wps_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid) 00350 { 00351 if (!wpa_s->ap_iface) 00352 return -1; 00353 return hostapd_wps_button_pushed(wpa_s->ap_iface->bss[0]); 00354 } 00355 00356 00357 int wpa_supplicant_ap_wps_pin(struct wpa_supplicant *wpa_s, const u8 *bssid, 00358 const char *pin, char *buf, size_t buflen) 00359 { 00360 int ret, ret_len = 0; 00361 00362 if (!wpa_s->ap_iface) 00363 return -1; 00364 00365 if (pin == NULL) { 00366 unsigned int rpin = wps_generate_pin(); 00367 ret_len = os_snprintf(buf, buflen, "%d", rpin); 00368 pin = buf; 00369 } 00370 00371 ret = hostapd_wps_add_pin(wpa_s->ap_iface->bss[0], "any", pin, 0); 00372 if (ret) 00373 return -1; 00374 return ret_len; 00375 } 00376 00377 #endif /* CONFIG_WPS */ 00378 00379 00380 #ifdef CONFIG_CTRL_IFACE 00381 00382 int ap_ctrl_iface_sta_first(struct wpa_supplicant *wpa_s, 00383 char *buf, size_t buflen) 00384 { 00385 if (wpa_s->ap_iface == NULL) 00386 return -1; 00387 return hostapd_ctrl_iface_sta_first(wpa_s->ap_iface->bss[0], 00388 buf, buflen); 00389 } 00390 00391 00392 int ap_ctrl_iface_sta(struct wpa_supplicant *wpa_s, const char *txtaddr, 00393 char *buf, size_t buflen) 00394 { 00395 if (wpa_s->ap_iface == NULL) 00396 return -1; 00397 return hostapd_ctrl_iface_sta(wpa_s->ap_iface->bss[0], txtaddr, 00398 buf, buflen); 00399 } 00400 00401 00402 int ap_ctrl_iface_sta_next(struct wpa_supplicant *wpa_s, const char *txtaddr, 00403 char *buf, size_t buflen) 00404 { 00405 if (wpa_s->ap_iface == NULL) 00406 return -1; 00407 return hostapd_ctrl_iface_sta_next(wpa_s->ap_iface->bss[0], txtaddr, 00408 buf, buflen); 00409 } 00410 00411 00412 int ap_ctrl_iface_wpa_get_status(struct wpa_supplicant *wpa_s, char *buf, 00413 size_t buflen, int verbose) 00414 { 00415 char *pos = buf, *end = buf + buflen; 00416 int ret; 00417 struct hostapd_bss_config *conf; 00418 00419 if (wpa_s->ap_iface == NULL) 00420 return -1; 00421 00422 conf = wpa_s->ap_iface->bss[0]->conf; 00423 if (conf->wpa == 0) 00424 return 0; 00425 00426 ret = os_snprintf(pos, end - pos, 00427 "pairwise_cipher=%s\n" 00428 "group_cipher=%s\n" 00429 "key_mgmt=%s\n", 00430 wpa_cipher_txt(conf->rsn_pairwise), 00431 wpa_cipher_txt(conf->wpa_group), 00432 wpa_key_mgmt_txt(conf->wpa_key_mgmt, 00433 conf->wpa)); 00434 if (ret < 0 || ret >= end - pos) 00435 return pos - buf; 00436 pos += ret; 00437 return pos - buf; 00438 } 00439 00440 #endif /* CONFIG_CTRL_IFACE */ 00441 00442 00443 int wpa_supplicant_ap_mac_addr_filter(struct wpa_supplicant *wpa_s, 00444 const u8 *addr) 00445 { 00446 struct hostapd_data *hapd; 00447 struct hostapd_bss_config *conf; 00448 00449 if (!wpa_s->ap_iface) 00450 return -1; 00451 00452 if (addr) 00453 wpa_printf(MSG_DEBUG, "AP: Set MAC address filter: " MACSTR, 00454 MAC2STR(addr)); 00455 else 00456 wpa_printf(MSG_DEBUG, "AP: Clear MAC address filter"); 00457 00458 hapd = wpa_s->ap_iface->bss[0]; 00459 conf = hapd->conf; 00460 00461 os_free(conf->accept_mac); 00462 conf->accept_mac = NULL; 00463 conf->num_accept_mac = 0; 00464 os_free(conf->deny_mac); 00465 conf->deny_mac = NULL; 00466 conf->num_deny_mac = 0; 00467 00468 if (addr == NULL) { 00469 conf->macaddr_acl = ACCEPT_UNLESS_DENIED; 00470 return 0; 00471 } 00472 00473 conf->macaddr_acl = DENY_UNLESS_ACCEPTED; 00474 conf->accept_mac = os_zalloc(sizeof(struct mac_acl_entry)); 00475 if (conf->accept_mac == NULL) 00476 return -1; 00477 os_memcpy(conf->accept_mac[0].addr, addr, ETH_ALEN); 00478 conf->num_accept_mac = 1; 00479 00480 return 0; 00481 }