ap.c
Go to the documentation of this file.
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(&params, 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, &params) < 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 }


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:34:33