hostapd.c
Go to the documentation of this file.
00001 /*
00002  * hostapd / Initialization and configuration
00003  * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
00013  */
00014 
00015 #include "utils/includes.h"
00016 
00017 #include "utils/common.h"
00018 #include "utils/eloop.h"
00019 #include "common/ieee802_11_defs.h"
00020 #include "radius/radius_client.h"
00021 #include "drivers/driver.h"
00022 #include "hostapd.h"
00023 #include "authsrv.h"
00024 #include "sta_info.h"
00025 #include "accounting.h"
00026 #include "ap_list.h"
00027 #include "beacon.h"
00028 #include "iapp.h"
00029 #include "ieee802_1x.h"
00030 #include "ieee802_11_auth.h"
00031 #include "vlan_init.h"
00032 #include "wpa_auth.h"
00033 #include "wps_hostapd.h"
00034 #include "hw_features.h"
00035 #include "wpa_auth_glue.h"
00036 #include "ap_drv_ops.h"
00037 #include "ap_config.h"
00038 
00039 
00040 static int hostapd_flush_old_stations(struct hostapd_data *hapd);
00041 static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd);
00042 
00043 extern int wpa_debug_level;
00044 
00045 
00046 int hostapd_reload_config(struct hostapd_iface *iface)
00047 {
00048         struct hostapd_data *hapd = iface->bss[0];
00049         struct hostapd_config *newconf, *oldconf;
00050         size_t j;
00051 
00052         if (iface->config_read_cb == NULL)
00053                 return -1;
00054         newconf = iface->config_read_cb(iface->config_fname);
00055         if (newconf == NULL)
00056                 return -1;
00057 
00058         /*
00059          * Deauthenticate all stations since the new configuration may not
00060          * allow them to use the BSS anymore.
00061          */
00062         for (j = 0; j < iface->num_bss; j++)
00063                 hostapd_flush_old_stations(iface->bss[j]);
00064 
00065 #ifndef CONFIG_NO_RADIUS
00066         /* TODO: update dynamic data based on changed configuration
00067          * items (e.g., open/close sockets, etc.) */
00068         radius_client_flush(hapd->radius, 0);
00069 #endif /* CONFIG_NO_RADIUS */
00070 
00071         oldconf = hapd->iconf;
00072         hapd->iconf = newconf;
00073         hapd->conf = &newconf->bss[0];
00074         iface->conf = newconf;
00075 
00076         if (hostapd_setup_wpa_psk(hapd->conf)) {
00077                 wpa_printf(MSG_ERROR, "Failed to re-configure WPA PSK "
00078                            "after reloading configuration");
00079         }
00080 
00081         if (hapd->conf->wpa && hapd->wpa_auth == NULL)
00082                 hostapd_setup_wpa(hapd);
00083         else if (hapd->conf->wpa) {
00084                 const u8 *wpa_ie;
00085                 size_t wpa_ie_len;
00086                 hostapd_reconfig_wpa(hapd);
00087                 wpa_ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &wpa_ie_len);
00088                 if (hostapd_set_generic_elem(hapd, wpa_ie, wpa_ie_len))
00089                         wpa_printf(MSG_ERROR, "Failed to configure WPA IE for "
00090                                    "the kernel driver.");
00091         } else if (hapd->wpa_auth) {
00092                 wpa_deinit(hapd->wpa_auth);
00093                 hapd->wpa_auth = NULL;
00094                 hostapd_set_privacy(hapd, 0);
00095                 hostapd_setup_encryption(hapd->conf->iface, hapd);
00096                 hostapd_set_generic_elem(hapd, (u8 *) "", 0);
00097         }
00098 
00099         ieee802_11_set_beacon(hapd);
00100 
00101         if (hapd->conf->ssid.ssid_set &&
00102             hostapd_set_ssid(hapd, (u8 *) hapd->conf->ssid.ssid,
00103                              hapd->conf->ssid.ssid_len)) {
00104                 wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver");
00105                 /* try to continue */
00106         }
00107 
00108         if (hapd->conf->ieee802_1x || hapd->conf->wpa)
00109                 hapd->drv.set_drv_ieee8021x(hapd, hapd->conf->iface, 1);
00110         else
00111                 hapd->drv.set_drv_ieee8021x(hapd, hapd->conf->iface, 0);
00112 
00113         hostapd_config_free(oldconf);
00114 
00115         wpa_printf(MSG_DEBUG, "Reconfigured interface %s", hapd->conf->iface);
00116 
00117         return 0;
00118 }
00119 
00120 
00121 static void hostapd_broadcast_key_clear_iface(struct hostapd_data *hapd,
00122                                               char *ifname)
00123 {
00124         int i;
00125 
00126         for (i = 0; i < NUM_WEP_KEYS; i++) {
00127                 if (hapd->drv.set_key(ifname, hapd, WPA_ALG_NONE, NULL, i,
00128                                       i == 0 ? 1 : 0, NULL, 0, NULL, 0)) {
00129                         wpa_printf(MSG_DEBUG, "Failed to clear default "
00130                                    "encryption keys (ifname=%s keyidx=%d)",
00131                                    ifname, i);
00132                 }
00133         }
00134 #ifdef CONFIG_IEEE80211W
00135         if (hapd->conf->ieee80211w) {
00136                 for (i = NUM_WEP_KEYS; i < NUM_WEP_KEYS + 2; i++) {
00137                         if (hapd->drv.set_key(ifname, hapd, WPA_ALG_NONE, NULL,
00138                                               i, i == 0 ? 1 : 0, NULL, 0,
00139                                               NULL, 0)) {
00140                                 wpa_printf(MSG_DEBUG, "Failed to clear "
00141                                            "default mgmt encryption keys "
00142                                            "(ifname=%s keyidx=%d)", ifname, i);
00143                         }
00144                 }
00145         }
00146 #endif /* CONFIG_IEEE80211W */
00147 }
00148 
00149 
00150 static int hostapd_broadcast_wep_clear(struct hostapd_data *hapd)
00151 {
00152         hostapd_broadcast_key_clear_iface(hapd, hapd->conf->iface);
00153         return 0;
00154 }
00155 
00156 
00157 static int hostapd_broadcast_wep_set(struct hostapd_data *hapd)
00158 {
00159         int errors = 0, idx;
00160         struct hostapd_ssid *ssid = &hapd->conf->ssid;
00161 
00162         idx = ssid->wep.idx;
00163         if (ssid->wep.default_len &&
00164             hapd->drv.set_key(hapd->conf->iface,
00165                               hapd, WPA_ALG_WEP, NULL, idx,
00166                               idx == ssid->wep.idx,
00167                               NULL, 0, ssid->wep.key[idx],
00168                               ssid->wep.len[idx])) {
00169                 wpa_printf(MSG_WARNING, "Could not set WEP encryption.");
00170                 errors++;
00171         }
00172 
00173         if (ssid->dyn_vlan_keys) {
00174                 size_t i;
00175                 for (i = 0; i <= ssid->max_dyn_vlan_keys; i++) {
00176                         const char *ifname;
00177                         struct hostapd_wep_keys *key = ssid->dyn_vlan_keys[i];
00178                         if (key == NULL)
00179                                 continue;
00180                         ifname = hostapd_get_vlan_id_ifname(hapd->conf->vlan,
00181                                                             i);
00182                         if (ifname == NULL)
00183                                 continue;
00184 
00185                         idx = key->idx;
00186                         if (hapd->drv.set_key(ifname, hapd, WPA_ALG_WEP, NULL,
00187                                               idx, idx == key->idx, NULL, 0,
00188                                               key->key[idx], key->len[idx])) {
00189                                 wpa_printf(MSG_WARNING, "Could not set "
00190                                            "dynamic VLAN WEP encryption.");
00191                                 errors++;
00192                         }
00193                 }
00194         }
00195 
00196         return errors;
00197 }
00198 
00209 static void hostapd_cleanup(struct hostapd_data *hapd)
00210 {
00211         if (hapd->iface->ctrl_iface_deinit)
00212                 hapd->iface->ctrl_iface_deinit(hapd);
00213 
00214         iapp_deinit(hapd->iapp);
00215         hapd->iapp = NULL;
00216         accounting_deinit(hapd);
00217         hostapd_deinit_wpa(hapd);
00218         vlan_deinit(hapd);
00219         hostapd_acl_deinit(hapd);
00220 #ifndef CONFIG_NO_RADIUS
00221         radius_client_deinit(hapd->radius);
00222         hapd->radius = NULL;
00223 #endif /* CONFIG_NO_RADIUS */
00224 
00225         hostapd_deinit_wps(hapd);
00226 
00227         authsrv_deinit(hapd);
00228 
00229         if (hapd->interface_added &&
00230             hostapd_if_remove(hapd, WPA_IF_AP_BSS, hapd->conf->iface)) {
00231                 wpa_printf(MSG_WARNING, "Failed to remove BSS interface %s",
00232                            hapd->conf->iface);
00233         }
00234 
00235         os_free(hapd->probereq_cb);
00236         hapd->probereq_cb = NULL;
00237 }
00238 
00239 
00247 static void hostapd_cleanup_iface_pre(struct hostapd_iface *iface)
00248 {
00249 }
00250 
00251 
00259 static void hostapd_cleanup_iface(struct hostapd_iface *iface)
00260 {
00261         hostapd_free_hw_features(iface->hw_features, iface->num_hw_features);
00262         iface->hw_features = NULL;
00263         os_free(iface->current_rates);
00264         iface->current_rates = NULL;
00265         ap_list_deinit(iface);
00266         hostapd_config_free(iface->conf);
00267         iface->conf = NULL;
00268 
00269         os_free(iface->config_fname);
00270         os_free(iface->bss);
00271         os_free(iface);
00272 }
00273 
00274 
00275 static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd)
00276 {
00277         int i;
00278 
00279         hostapd_broadcast_wep_set(hapd);
00280 
00281         if (hapd->conf->ssid.wep.default_len) {
00282                 hostapd_set_privacy(hapd, 1);
00283                 return 0;
00284         }
00285 
00286         for (i = 0; i < 4; i++) {
00287                 if (hapd->conf->ssid.wep.key[i] &&
00288                     hapd->drv.set_key(iface, hapd, WPA_ALG_WEP, NULL, i,
00289                                       i == hapd->conf->ssid.wep.idx, NULL, 0,
00290                                       hapd->conf->ssid.wep.key[i],
00291                                       hapd->conf->ssid.wep.len[i])) {
00292                         wpa_printf(MSG_WARNING, "Could not set WEP "
00293                                    "encryption.");
00294                         return -1;
00295                 }
00296                 if (hapd->conf->ssid.wep.key[i] &&
00297                     i == hapd->conf->ssid.wep.idx)
00298                         hostapd_set_privacy(hapd, 1);
00299         }
00300 
00301         return 0;
00302 }
00303 
00304 
00305 static int hostapd_flush_old_stations(struct hostapd_data *hapd)
00306 {
00307         int ret = 0;
00308 
00309         if (hostapd_drv_none(hapd) || hapd->drv_priv == NULL)
00310                 return 0;
00311 
00312         wpa_printf(MSG_DEBUG, "Flushing old station entries");
00313         if (hostapd_flush(hapd)) {
00314                 wpa_printf(MSG_WARNING, "Could not connect to kernel driver.");
00315                 ret = -1;
00316         }
00317         wpa_printf(MSG_DEBUG, "Deauthenticate all stations");
00318 
00319         /* New Prism2.5/3 STA firmware versions seem to have issues with this
00320          * broadcast deauth frame. This gets the firmware in odd state where
00321          * nothing works correctly, so let's skip sending this for the hostap
00322          * driver. */
00323         if (hapd->driver && os_strcmp(hapd->driver->name, "hostap") != 0) {
00324                 u8 addr[ETH_ALEN];
00325                 os_memset(addr, 0xff, ETH_ALEN);
00326                 hapd->drv.sta_deauth(hapd, addr,
00327                                      WLAN_REASON_PREV_AUTH_NOT_VALID);
00328         }
00329 
00330         return ret;
00331 }
00332 
00333 
00341 static int hostapd_validate_bssid_configuration(struct hostapd_iface *iface)
00342 {
00343         u8 mask[ETH_ALEN] = { 0 };
00344         struct hostapd_data *hapd = iface->bss[0];
00345         unsigned int i = iface->conf->num_bss, bits = 0, j;
00346         int res;
00347         int auto_addr = 0;
00348 
00349         if (hostapd_drv_none(hapd))
00350                 return 0;
00351 
00352         /* Generate BSSID mask that is large enough to cover the BSSIDs. */
00353 
00354         /* Determine the bits necessary to cover the number of BSSIDs. */
00355         for (i--; i; i >>= 1)
00356                 bits++;
00357 
00358         /* Determine the bits necessary to any configured BSSIDs,
00359            if they are higher than the number of BSSIDs. */
00360         for (j = 0; j < iface->conf->num_bss; j++) {
00361                 if (hostapd_mac_comp_empty(iface->conf->bss[j].bssid) == 0) {
00362                         if (j)
00363                                 auto_addr++;
00364                         continue;
00365                 }
00366 
00367                 for (i = 0; i < ETH_ALEN; i++) {
00368                         mask[i] |=
00369                                 iface->conf->bss[j].bssid[i] ^
00370                                 hapd->own_addr[i];
00371                 }
00372         }
00373 
00374         if (!auto_addr)
00375                 goto skip_mask_ext;
00376 
00377         for (i = 0; i < ETH_ALEN && mask[i] == 0; i++)
00378                 ;
00379         j = 0;
00380         if (i < ETH_ALEN) {
00381                 j = (5 - i) * 8;
00382 
00383                 while (mask[i] != 0) {
00384                         mask[i] >>= 1;
00385                         j++;
00386                 }
00387         }
00388 
00389         if (bits < j)
00390                 bits = j;
00391 
00392         if (bits > 40) {
00393                 wpa_printf(MSG_ERROR, "Too many bits in the BSSID mask (%u)",
00394                            bits);
00395                 return -1;
00396         }
00397 
00398         os_memset(mask, 0xff, ETH_ALEN);
00399         j = bits / 8;
00400         for (i = 5; i > 5 - j; i--)
00401                 mask[i] = 0;
00402         j = bits % 8;
00403         while (j--)
00404                 mask[i] <<= 1;
00405 
00406 skip_mask_ext:
00407         wpa_printf(MSG_DEBUG, "BSS count %lu, BSSID mask " MACSTR " (%d bits)",
00408                    (unsigned long) iface->conf->num_bss, MAC2STR(mask), bits);
00409 
00410         res = hostapd_valid_bss_mask(hapd, hapd->own_addr, mask);
00411         if (res == 0)
00412                 return 0;
00413 
00414         if (res < 0) {
00415                 wpa_printf(MSG_ERROR, "Driver did not accept BSSID mask "
00416                            MACSTR " for start address " MACSTR ".",
00417                            MAC2STR(mask), MAC2STR(hapd->own_addr));
00418                 return -1;
00419         }
00420 
00421         if (!auto_addr)
00422                 return 0;
00423 
00424         for (i = 0; i < ETH_ALEN; i++) {
00425                 if ((hapd->own_addr[i] & mask[i]) != hapd->own_addr[i]) {
00426                         wpa_printf(MSG_ERROR, "Invalid BSSID mask " MACSTR
00427                                    " for start address " MACSTR ".",
00428                                    MAC2STR(mask), MAC2STR(hapd->own_addr));
00429                         wpa_printf(MSG_ERROR, "Start address must be the "
00430                                    "first address in the block (i.e., addr "
00431                                    "AND mask == addr).");
00432                         return -1;
00433                 }
00434         }
00435 
00436         return 0;
00437 }
00438 
00439 
00440 static int mac_in_conf(struct hostapd_config *conf, const void *a)
00441 {
00442         size_t i;
00443 
00444         for (i = 0; i < conf->num_bss; i++) {
00445                 if (hostapd_mac_comp(conf->bss[i].bssid, a) == 0) {
00446                         return 1;
00447                 }
00448         }
00449 
00450         return 0;
00451 }
00452 
00453 
00454 
00455 
00466 static int hostapd_setup_bss(struct hostapd_data *hapd, int first)
00467 {
00468         struct hostapd_bss_config *conf = hapd->conf;
00469         u8 ssid[HOSTAPD_MAX_SSID_LEN + 1];
00470         int ssid_len, set_ssid;
00471         char force_ifname[IFNAMSIZ];
00472         u8 if_addr[ETH_ALEN];
00473 
00474         if (!first) {
00475                 if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0) {
00476                         /* Allocate the next available BSSID. */
00477                         do {
00478                                 inc_byte_array(hapd->own_addr, ETH_ALEN);
00479                         } while (mac_in_conf(hapd->iconf, hapd->own_addr));
00480                 } else {
00481                         /* Allocate the configured BSSID. */
00482                         os_memcpy(hapd->own_addr, hapd->conf->bssid, ETH_ALEN);
00483 
00484                         if (hostapd_mac_comp(hapd->own_addr,
00485                                              hapd->iface->bss[0]->own_addr) ==
00486                             0) {
00487                                 wpa_printf(MSG_ERROR, "BSS '%s' may not have "
00488                                            "BSSID set to the MAC address of "
00489                                            "the radio", hapd->conf->iface);
00490                                 return -1;
00491                         }
00492                 }
00493 
00494                 hapd->interface_added = 1;
00495                 if (hostapd_if_add(hapd->iface->bss[0], WPA_IF_AP_BSS,
00496                                    hapd->conf->iface, hapd->own_addr, hapd,
00497                                    &hapd->drv_priv, force_ifname, if_addr)) {
00498                         wpa_printf(MSG_ERROR, "Failed to add BSS (BSSID="
00499                                    MACSTR ")", MAC2STR(hapd->own_addr));
00500                         return -1;
00501                 }
00502         }
00503 
00504         hostapd_flush_old_stations(hapd);
00505         hostapd_set_privacy(hapd, 0);
00506 
00507         hostapd_broadcast_wep_clear(hapd);
00508         if (hostapd_setup_encryption(hapd->conf->iface, hapd))
00509                 return -1;
00510 
00511         /*
00512          * Fetch the SSID from the system and use it or,
00513          * if one was specified in the config file, verify they
00514          * match.
00515          */
00516         ssid_len = hostapd_get_ssid(hapd, ssid, sizeof(ssid));
00517         if (ssid_len < 0) {
00518                 wpa_printf(MSG_ERROR, "Could not read SSID from system");
00519                 return -1;
00520         }
00521         if (conf->ssid.ssid_set) {
00522                 /*
00523                  * If SSID is specified in the config file and it differs
00524                  * from what is being used then force installation of the
00525                  * new SSID.
00526                  */
00527                 set_ssid = (conf->ssid.ssid_len != (size_t) ssid_len ||
00528                             os_memcmp(conf->ssid.ssid, ssid, ssid_len) != 0);
00529         } else {
00530                 /*
00531                  * No SSID in the config file; just use the one we got
00532                  * from the system.
00533                  */
00534                 set_ssid = 0;
00535                 conf->ssid.ssid_len = ssid_len;
00536                 os_memcpy(conf->ssid.ssid, ssid, conf->ssid.ssid_len);
00537                 conf->ssid.ssid[conf->ssid.ssid_len] = '\0';
00538         }
00539 
00540         if (!hostapd_drv_none(hapd)) {
00541                 wpa_printf(MSG_ERROR, "Using interface %s with hwaddr " MACSTR
00542                            " and ssid '%s'",
00543                            hapd->conf->iface, MAC2STR(hapd->own_addr),
00544                            hapd->conf->ssid.ssid);
00545         }
00546 
00547         if (hostapd_setup_wpa_psk(conf)) {
00548                 wpa_printf(MSG_ERROR, "WPA-PSK setup failed.");
00549                 return -1;
00550         }
00551 
00552         /* Set SSID for the kernel driver (to be used in beacon and probe
00553          * response frames) */
00554         if (set_ssid && hostapd_set_ssid(hapd, (u8 *) conf->ssid.ssid,
00555                                          conf->ssid.ssid_len)) {
00556                 wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver");
00557                 return -1;
00558         }
00559 
00560         if (wpa_debug_level == MSG_MSGDUMP)
00561                 conf->radius->msg_dumps = 1;
00562 #ifndef CONFIG_NO_RADIUS
00563         hapd->radius = radius_client_init(hapd, conf->radius);
00564         if (hapd->radius == NULL) {
00565                 wpa_printf(MSG_ERROR, "RADIUS client initialization failed.");
00566                 return -1;
00567         }
00568 #endif /* CONFIG_NO_RADIUS */
00569 
00570         if (hostapd_acl_init(hapd)) {
00571                 wpa_printf(MSG_ERROR, "ACL initialization failed.");
00572                 return -1;
00573         }
00574         if (hostapd_init_wps(hapd, conf))
00575                 return -1;
00576 
00577         if (authsrv_init(hapd) < 0)
00578                 return -1;
00579 
00580         if (ieee802_1x_init(hapd)) {
00581                 wpa_printf(MSG_ERROR, "IEEE 802.1X initialization failed.");
00582                 return -1;
00583         }
00584 
00585         if (hapd->conf->wpa && hostapd_setup_wpa(hapd))
00586                 return -1;
00587 
00588         if (accounting_init(hapd)) {
00589                 wpa_printf(MSG_ERROR, "Accounting initialization failed.");
00590                 return -1;
00591         }
00592 
00593         if (hapd->conf->ieee802_11f &&
00594             (hapd->iapp = iapp_init(hapd, hapd->conf->iapp_iface)) == NULL) {
00595                 wpa_printf(MSG_ERROR, "IEEE 802.11F (IAPP) initialization "
00596                            "failed.");
00597                 return -1;
00598         }
00599 
00600         if (hapd->iface->ctrl_iface_init &&
00601             hapd->iface->ctrl_iface_init(hapd)) {
00602                 wpa_printf(MSG_ERROR, "Failed to setup control interface");
00603                 return -1;
00604         }
00605 
00606         if (!hostapd_drv_none(hapd) && vlan_init(hapd)) {
00607                 wpa_printf(MSG_ERROR, "VLAN initialization failed.");
00608                 return -1;
00609         }
00610 
00611         ieee802_11_set_beacon(hapd);
00612 
00613         return 0;
00614 }
00615 
00616 
00617 static void hostapd_tx_queue_params(struct hostapd_iface *iface)
00618 {
00619         struct hostapd_data *hapd = iface->bss[0];
00620         int i;
00621         struct hostapd_tx_queue_params *p;
00622 
00623         for (i = 0; i < NUM_TX_QUEUES; i++) {
00624                 p = &iface->conf->tx_queue[i];
00625 
00626                 if (!p->configured)
00627                         continue;
00628 
00629                 if (hostapd_set_tx_queue_params(hapd, i, p->aifs, p->cwmin,
00630                                                 p->cwmax, p->burst)) {
00631                         wpa_printf(MSG_DEBUG, "Failed to set TX queue "
00632                                    "parameters for queue %d.", i);
00633                         /* Continue anyway */
00634                 }
00635         }
00636 }
00637 
00638 
00639 static int setup_interface(struct hostapd_iface *iface)
00640 {
00641         struct hostapd_data *hapd = iface->bss[0];
00642         size_t i;
00643         char country[4];
00644 
00645         /*
00646          * Make sure that all BSSes get configured with a pointer to the same
00647          * driver interface.
00648          */
00649         for (i = 1; i < iface->num_bss; i++) {
00650                 iface->bss[i]->driver = hapd->driver;
00651                 iface->bss[i]->drv_priv = hapd->drv_priv;
00652         }
00653 
00654         if (hostapd_validate_bssid_configuration(iface))
00655                 return -1;
00656 
00657         if (hapd->iconf->country[0] && hapd->iconf->country[1]) {
00658                 os_memcpy(country, hapd->iconf->country, 3);
00659                 country[3] = '\0';
00660                 if (hostapd_set_country(hapd, country) < 0) {
00661                         wpa_printf(MSG_ERROR, "Failed to set country code");
00662                         return -1;
00663                 }
00664         }
00665 
00666         if (hostapd_get_hw_features(iface)) {
00667                 /* Not all drivers support this yet, so continue without hw
00668                  * feature data. */
00669         } else {
00670                 int ret = hostapd_select_hw_mode(iface);
00671                 if (ret < 0) {
00672                         wpa_printf(MSG_ERROR, "Could not select hw_mode and "
00673                                    "channel. (%d)", ret);
00674                         return -1;
00675                 }
00676                 ret = hostapd_check_ht_capab(iface);
00677                 if (ret < 0)
00678                         return -1;
00679                 if (ret == 1) {
00680                         wpa_printf(MSG_DEBUG, "Interface initialization will "
00681                                    "be completed in a callback");
00682                         return 0;
00683                 }
00684         }
00685         return hostapd_setup_interface_complete(iface, 0);
00686 }
00687 
00688 
00689 int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err)
00690 {
00691         struct hostapd_data *hapd = iface->bss[0];
00692         size_t j;
00693         u8 *prev_addr;
00694 
00695         if (err) {
00696                 wpa_printf(MSG_ERROR, "Interface initialization failed");
00697                 eloop_terminate();
00698                 return -1;
00699         }
00700 
00701         wpa_printf(MSG_DEBUG, "Completing interface initialization");
00702         if (hapd->iconf->channel) {
00703                 iface->freq = hostapd_hw_get_freq(hapd, hapd->iconf->channel);
00704                 wpa_printf(MSG_DEBUG, "Mode: %s  Channel: %d  "
00705                            "Frequency: %d MHz",
00706                            hostapd_hw_mode_txt(hapd->iconf->hw_mode),
00707                            hapd->iconf->channel, iface->freq);
00708 
00709                 if (hostapd_set_freq(hapd, hapd->iconf->hw_mode, iface->freq,
00710                                      hapd->iconf->channel,
00711                                      hapd->iconf->ieee80211n,
00712                                      hapd->iconf->secondary_channel)) {
00713                         wpa_printf(MSG_ERROR, "Could not set channel for "
00714                                    "kernel driver");
00715                         return -1;
00716                 }
00717         }
00718 
00719         if (hapd->iconf->rts_threshold > -1 &&
00720             hostapd_set_rts(hapd, hapd->iconf->rts_threshold)) {
00721                 wpa_printf(MSG_ERROR, "Could not set RTS threshold for "
00722                            "kernel driver");
00723                 return -1;
00724         }
00725 
00726         if (hapd->iconf->fragm_threshold > -1 &&
00727             hostapd_set_frag(hapd, hapd->iconf->fragm_threshold)) {
00728                 wpa_printf(MSG_ERROR, "Could not set fragmentation threshold "
00729                            "for kernel driver");
00730                 return -1;
00731         }
00732 
00733         prev_addr = hapd->own_addr;
00734 
00735         for (j = 0; j < iface->num_bss; j++) {
00736                 hapd = iface->bss[j];
00737                 if (j)
00738                         os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN);
00739                 if (hostapd_setup_bss(hapd, j == 0))
00740                         return -1;
00741                 if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0)
00742                         prev_addr = hapd->own_addr;
00743         }
00744 
00745         hostapd_tx_queue_params(iface);
00746 
00747         ap_list_init(iface);
00748 
00749         if (hostapd_driver_commit(hapd) < 0) {
00750                 wpa_printf(MSG_ERROR, "%s: Failed to commit driver "
00751                            "configuration", __func__);
00752                 return -1;
00753         }
00754 
00755         wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
00756                    iface->bss[0]->conf->iface);
00757 
00758         return 0;
00759 }
00760 
00761 
00772 int hostapd_setup_interface(struct hostapd_iface *iface)
00773 {
00774         int ret;
00775 
00776         ret = setup_interface(iface);
00777         if (ret) {
00778                 wpa_printf(MSG_ERROR, "%s: Unable to setup interface.",
00779                            iface->bss[0]->conf->iface);
00780                 return -1;
00781         }
00782 
00783         return 0;
00784 }
00785 
00786 
00798 struct hostapd_data *
00799 hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface,
00800                        struct hostapd_config *conf,
00801                        struct hostapd_bss_config *bss)
00802 {
00803         struct hostapd_data *hapd;
00804 
00805         hapd = os_zalloc(sizeof(*hapd));
00806         if (hapd == NULL)
00807                 return NULL;
00808 
00809         hostapd_set_driver_ops(&hapd->drv);
00810         hapd->new_assoc_sta_cb = hostapd_new_assoc_sta;
00811         hapd->iconf = conf;
00812         hapd->conf = bss;
00813         hapd->iface = hapd_iface;
00814         hapd->driver = hapd->iconf->driver;
00815 
00816         return hapd;
00817 }
00818 
00819 
00820 void hostapd_interface_deinit(struct hostapd_iface *iface)
00821 {
00822         size_t j;
00823 
00824         if (iface == NULL)
00825                 return;
00826 
00827         hostapd_cleanup_iface_pre(iface);
00828         for (j = 0; j < iface->num_bss; j++) {
00829                 struct hostapd_data *hapd = iface->bss[j];
00830                 hostapd_free_stas(hapd);
00831                 hostapd_flush_old_stations(hapd);
00832                 hostapd_cleanup(hapd);
00833         }
00834 }
00835 
00836 
00837 void hostapd_interface_free(struct hostapd_iface *iface)
00838 {
00839         size_t j;
00840         for (j = 0; j < iface->num_bss; j++)
00841                 os_free(iface->bss[j]);
00842         hostapd_cleanup_iface(iface);
00843 }
00844 
00845 
00857 void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
00858                            int reassoc)
00859 {
00860         if (hapd->tkip_countermeasures) {
00861                 hapd->drv.sta_deauth(hapd, sta->addr,
00862                                      WLAN_REASON_MICHAEL_MIC_FAILURE);
00863                 return;
00864         }
00865 
00866         hostapd_prune_associations(hapd, sta->addr);
00867 
00868         /* IEEE 802.11F (IAPP) */
00869         if (hapd->conf->ieee802_11f)
00870                 iapp_new_station(hapd->iapp, sta);
00871 
00872         /* Start accounting here, if IEEE 802.1X and WPA are not used.
00873          * IEEE 802.1X/WPA code will start accounting after the station has
00874          * been authorized. */
00875         if (!hapd->conf->ieee802_1x && !hapd->conf->wpa)
00876                 accounting_sta_start(hapd, sta);
00877 
00878         /* Start IEEE 802.1X authentication process for new stations */
00879         ieee802_1x_new_station(hapd, sta);
00880         if (reassoc) {
00881                 if (sta->auth_alg != WLAN_AUTH_FT &&
00882                     !(sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS)))
00883                         wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH);
00884         } else
00885                 wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm);
00886 }


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