sta_info.c

Go to the documentation of this file.
00001 
00017 #include "includes.h"
00018 
00019 #include "hostapd.h"
00020 #include "sta_info.h"
00021 #include "eloop.h"
00022 #include "accounting.h"
00023 #include "ieee802_1x.h"
00024 #include "ieee802_11.h"
00025 #include "radius/radius.h"
00026 #include "wpa.h"
00027 #include "preauth.h"
00028 #include "radius/radius_client.h"
00029 #include "driver_i.h"
00030 #include "beacon.h"
00031 #include "hw_features.h"
00032 #include "mlme.h"
00033 #include "vlan_init.h"
00034 
00035 static int ap_sta_in_other_bss(struct hostapd_data *hapd,
00036                                struct sta_info *sta, u32 flags);
00037 static void ap_handle_session_timer(void *eloop_ctx, void *timeout_ctx);
00038 #ifdef CONFIG_IEEE80211W
00039 static void ap_sa_query_timer(void *eloop_ctx, void *timeout_ctx);
00040 #endif /* CONFIG_IEEE80211W */
00041 
00042 int ap_for_each_sta(struct hostapd_data *hapd,
00043                     int (*cb)(struct hostapd_data *hapd, struct sta_info *sta,
00044                               void *ctx),
00045                     void *ctx)
00046 {
00047         struct sta_info *sta;
00048 
00049         for (sta = hapd->sta_list; sta; sta = sta->next) {
00050                 if (cb(hapd, sta, ctx))
00051                         return 1;
00052         }
00053 
00054         return 0;
00055 }
00056 
00057 
00058 struct sta_info * ap_get_sta(struct hostapd_data *hapd, const u8 *sta)
00059 {
00060         struct sta_info *s;
00061 
00062         s = hapd->sta_hash[STA_HASH(sta)];
00063         while (s != NULL && os_memcmp(s->addr, sta, 6) != 0)
00064                 s = s->hnext;
00065         return s;
00066 }
00067 
00068 
00069 static void ap_sta_list_del(struct hostapd_data *hapd, struct sta_info *sta)
00070 {
00071         struct sta_info *tmp;
00072 
00073         if (hapd->sta_list == sta) {
00074                 hapd->sta_list = sta->next;
00075                 return;
00076         }
00077 
00078         tmp = hapd->sta_list;
00079         while (tmp != NULL && tmp->next != sta)
00080                 tmp = tmp->next;
00081         if (tmp == NULL) {
00082                 wpa_printf(MSG_DEBUG, "Could not remove STA " MACSTR " from "
00083                            "list.", MAC2STR(sta->addr));
00084         } else
00085                 tmp->next = sta->next;
00086 }
00087 
00088 
00089 void ap_sta_hash_add(struct hostapd_data *hapd, struct sta_info *sta)
00090 {
00091         sta->hnext = hapd->sta_hash[STA_HASH(sta->addr)];
00092         hapd->sta_hash[STA_HASH(sta->addr)] = sta;
00093 }
00094 
00095 
00096 static void ap_sta_hash_del(struct hostapd_data *hapd, struct sta_info *sta)
00097 {
00098         struct sta_info *s;
00099 
00100         s = hapd->sta_hash[STA_HASH(sta->addr)];
00101         if (s == NULL) return;
00102         if (os_memcmp(s->addr, sta->addr, 6) == 0) {
00103                 hapd->sta_hash[STA_HASH(sta->addr)] = s->hnext;
00104                 return;
00105         }
00106 
00107         while (s->hnext != NULL &&
00108                os_memcmp(s->hnext->addr, sta->addr, ETH_ALEN) != 0)
00109                 s = s->hnext;
00110         if (s->hnext != NULL)
00111                 s->hnext = s->hnext->hnext;
00112         else
00113                 wpa_printf(MSG_DEBUG, "AP: could not remove STA " MACSTR
00114                            " from hash table", MAC2STR(sta->addr));
00115 }
00116 
00117 
00118 void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
00119 {
00120         int set_beacon = 0;
00121 
00122         accounting_sta_stop(hapd, sta);
00123 
00124         if (!ap_sta_in_other_bss(hapd, sta, WLAN_STA_ASSOC) &&
00125             !(sta->flags & WLAN_STA_PREAUTH))
00126                 hostapd_sta_remove(hapd, sta->addr);
00127 
00128         ap_sta_hash_del(hapd, sta);
00129         ap_sta_list_del(hapd, sta);
00130 
00131         if (sta->aid > 0)
00132                 hapd->sta_aid[(sta->aid - 1) / 32] &=
00133                         ~BIT((sta->aid - 1) % 32);
00134 
00135         hapd->num_sta--;
00136         if (sta->nonerp_set) {
00137                 sta->nonerp_set = 0;
00138                 hapd->iface->num_sta_non_erp--;
00139                 if (hapd->iface->num_sta_non_erp == 0)
00140                         set_beacon++;
00141         }
00142 
00143         if (sta->no_short_slot_time_set) {
00144                 sta->no_short_slot_time_set = 0;
00145                 hapd->iface->num_sta_no_short_slot_time--;
00146                 if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
00147                     && hapd->iface->num_sta_no_short_slot_time == 0)
00148                         set_beacon++;
00149         }
00150 
00151         if (sta->no_short_preamble_set) {
00152                 sta->no_short_preamble_set = 0;
00153                 hapd->iface->num_sta_no_short_preamble--;
00154                 if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
00155                     && hapd->iface->num_sta_no_short_preamble == 0)
00156                         set_beacon++;
00157         }
00158 
00159 #ifdef CONFIG_IEEE80211N
00160         if (sta->no_ht_gf_set) {
00161                 sta->no_ht_gf_set = 0;
00162                 hapd->iface->num_sta_ht_no_gf--;
00163         }
00164 
00165         if (sta->no_ht_set) {
00166                 sta->no_ht_set = 0;
00167                 hapd->iface->num_sta_no_ht--;
00168         }
00169 
00170         if (sta->ht_20mhz_set) {
00171                 sta->ht_20mhz_set = 0;
00172                 hapd->iface->num_sta_ht_20mhz--;
00173         }
00174 
00175 #ifdef NEED_AP_MLME
00176         if (hostapd_ht_operation_update(hapd->iface) > 0)
00177                 set_beacon++;
00178 #endif /* NEED_AP_MLME */
00179 #endif /* CONFIG_IEEE80211N */
00180 
00181         if (set_beacon)
00182                 ieee802_11_set_beacons(hapd->iface);
00183 
00184         eloop_cancel_timeout(ap_handle_timer, hapd, sta);
00185         eloop_cancel_timeout(ap_handle_session_timer, hapd, sta);
00186 
00187         ieee802_1x_free_station(sta);
00188         wpa_auth_sta_deinit(sta->wpa_sm);
00189         rsn_preauth_free_station(hapd, sta);
00190         radius_client_flush_auth(hapd->radius, sta->addr);
00191 
00192         os_free(sta->last_assoc_req);
00193         os_free(sta->challenge);
00194 
00195 #ifdef CONFIG_IEEE80211W
00196         os_free(sta->sa_query_trans_id);
00197         eloop_cancel_timeout(ap_sa_query_timer, hapd, sta);
00198 #endif /* CONFIG_IEEE80211W */
00199 
00200         wpabuf_free(sta->wps_ie);
00201 
00202         os_free(sta);
00203 }
00204 
00205 
00206 void hostapd_free_stas(struct hostapd_data *hapd)
00207 {
00208         struct sta_info *sta, *prev;
00209 
00210         sta = hapd->sta_list;
00211 
00212         while (sta) {
00213                 prev = sta;
00214                 if (sta->flags & WLAN_STA_AUTH) {
00215                         mlme_deauthenticate_indication(
00216                                 hapd, sta, WLAN_REASON_UNSPECIFIED);
00217                 }
00218                 sta = sta->next;
00219                 wpa_printf(MSG_DEBUG, "Removing station " MACSTR,
00220                            MAC2STR(prev->addr));
00221                 ap_free_sta(hapd, prev);
00222         }
00223 }
00224 
00225 
00235 void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
00236 {
00237         struct hostapd_data *hapd = eloop_ctx;
00238         struct sta_info *sta = timeout_ctx;
00239         unsigned long next_time = 0;
00240 
00241         if (sta->timeout_next == STA_REMOVE) {
00242                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
00243                                HOSTAPD_LEVEL_INFO, "deauthenticated due to "
00244                                "local deauth request");
00245                 ap_free_sta(hapd, sta);
00246                 return;
00247         }
00248 
00249         if ((sta->flags & WLAN_STA_ASSOC) &&
00250             (sta->timeout_next == STA_NULLFUNC ||
00251              sta->timeout_next == STA_DISASSOC)) {
00252                 int inactive_sec;
00253                 wpa_printf(MSG_DEBUG, "Checking STA " MACSTR " inactivity:",
00254                            MAC2STR(sta->addr));
00255                 inactive_sec = hostapd_get_inact_sec(hapd, sta->addr);
00256                 if (inactive_sec == -1) {
00257                         wpa_printf(MSG_DEBUG, "Could not get station info "
00258                                    "from kernel driver for " MACSTR ".",
00259                                    MAC2STR(sta->addr));
00260                 } else if (inactive_sec < hapd->conf->ap_max_inactivity &&
00261                            sta->flags & WLAN_STA_ASSOC) {
00262                         /* station activity detected; reset timeout state */
00263                         wpa_printf(MSG_DEBUG, "  Station has been active");
00264                         sta->timeout_next = STA_NULLFUNC;
00265                         next_time = hapd->conf->ap_max_inactivity -
00266                                 inactive_sec;
00267                 }
00268         }
00269 
00270         if ((sta->flags & WLAN_STA_ASSOC) &&
00271             sta->timeout_next == STA_DISASSOC &&
00272             !(sta->flags & WLAN_STA_PENDING_POLL)) {
00273                 wpa_printf(MSG_DEBUG, "  Station has ACKed data poll");
00274                 /* data nullfunc frame poll did not produce TX errors; assume
00275                  * station ACKed it */
00276                 sta->timeout_next = STA_NULLFUNC;
00277                 next_time = hapd->conf->ap_max_inactivity;
00278         }
00279 
00280         if (next_time) {
00281                 eloop_register_timeout(next_time, 0, ap_handle_timer, hapd,
00282                                        sta);
00283                 return;
00284         }
00285 
00286         if (sta->timeout_next == STA_NULLFUNC &&
00287             (sta->flags & WLAN_STA_ASSOC)) {
00288                 /* send data frame to poll STA and check whether this frame
00289                  * is ACKed */
00290                 struct ieee80211_hdr hdr;
00291 
00292                 wpa_printf(MSG_DEBUG, "  Polling STA with data frame");
00293                 sta->flags |= WLAN_STA_PENDING_POLL;
00294 
00295 #ifndef CONFIG_NATIVE_WINDOWS
00296                 os_memset(&hdr, 0, sizeof(hdr));
00297                 if (hapd->driver &&
00298                     os_strcmp(hapd->driver->name, "hostap") == 0) {
00299                         /*
00300                          * WLAN_FC_STYPE_NULLFUNC would be more appropriate,
00301                          * but it is apparently not retried so TX Exc events
00302                          * are not received for it.
00303                          */
00304                         hdr.frame_control =
00305                                 IEEE80211_FC(WLAN_FC_TYPE_DATA,
00306                                              WLAN_FC_STYPE_DATA);
00307                 } else {
00308                         hdr.frame_control =
00309                                 IEEE80211_FC(WLAN_FC_TYPE_DATA,
00310                                              WLAN_FC_STYPE_NULLFUNC);
00311                 }
00312 
00313                 hdr.frame_control |= host_to_le16(WLAN_FC_FROMDS);
00314                 os_memcpy(hdr.IEEE80211_DA_FROMDS, sta->addr, ETH_ALEN);
00315                 os_memcpy(hdr.IEEE80211_BSSID_FROMDS, hapd->own_addr,
00316                           ETH_ALEN);
00317                 os_memcpy(hdr.IEEE80211_SA_FROMDS, hapd->own_addr, ETH_ALEN);
00318 
00319                 if (hostapd_send_mgmt_frame(hapd, &hdr, sizeof(hdr)) < 0)
00320                         perror("ap_handle_timer: send");
00321 #endif /* CONFIG_NATIVE_WINDOWS */
00322         } else if (sta->timeout_next != STA_REMOVE) {
00323                 int deauth = sta->timeout_next == STA_DEAUTH;
00324 
00325                 wpa_printf(MSG_DEBUG, "Sending %s info to STA " MACSTR,
00326                            deauth ? "deauthentication" : "disassociation",
00327                            MAC2STR(sta->addr));
00328 
00329                 if (deauth) {
00330                         hostapd_sta_deauth(hapd, sta->addr,
00331                                            WLAN_REASON_PREV_AUTH_NOT_VALID);
00332                 } else {
00333                         hostapd_sta_disassoc(
00334                                 hapd, sta->addr,
00335                                 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
00336                 }
00337         }
00338 
00339         switch (sta->timeout_next) {
00340         case STA_NULLFUNC:
00341                 sta->timeout_next = STA_DISASSOC;
00342                 eloop_register_timeout(AP_DISASSOC_DELAY, 0, ap_handle_timer,
00343                                        hapd, sta);
00344                 break;
00345         case STA_DISASSOC:
00346                 sta->flags &= ~WLAN_STA_ASSOC;
00347                 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
00348                 if (!sta->acct_terminate_cause)
00349                         sta->acct_terminate_cause =
00350                                 RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT;
00351                 accounting_sta_stop(hapd, sta);
00352                 ieee802_1x_free_station(sta);
00353                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
00354                                HOSTAPD_LEVEL_INFO, "disassociated due to "
00355                                "inactivity");
00356                 sta->timeout_next = STA_DEAUTH;
00357                 eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer,
00358                                        hapd, sta);
00359                 mlme_disassociate_indication(
00360                         hapd, sta, WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
00361                 break;
00362         case STA_DEAUTH:
00363         case STA_REMOVE:
00364                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
00365                                HOSTAPD_LEVEL_INFO, "deauthenticated due to "
00366                                "inactivity");
00367                 if (!sta->acct_terminate_cause)
00368                         sta->acct_terminate_cause =
00369                                 RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT;
00370                 mlme_deauthenticate_indication(
00371                         hapd, sta,
00372                         WLAN_REASON_PREV_AUTH_NOT_VALID);
00373                 ap_free_sta(hapd, sta);
00374                 break;
00375         }
00376 }
00377 
00378 
00379 static void ap_handle_session_timer(void *eloop_ctx, void *timeout_ctx)
00380 {
00381         struct hostapd_data *hapd = eloop_ctx;
00382         struct sta_info *sta = timeout_ctx;
00383         u8 addr[ETH_ALEN];
00384 
00385         if (!(sta->flags & WLAN_STA_AUTH))
00386                 return;
00387 
00388         mlme_deauthenticate_indication(hapd, sta,
00389                                        WLAN_REASON_PREV_AUTH_NOT_VALID);
00390         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
00391                        HOSTAPD_LEVEL_INFO, "deauthenticated due to "
00392                        "session timeout");
00393         sta->acct_terminate_cause =
00394                 RADIUS_ACCT_TERMINATE_CAUSE_SESSION_TIMEOUT;
00395         os_memcpy(addr, sta->addr, ETH_ALEN);
00396         ap_free_sta(hapd, sta);
00397         hostapd_sta_deauth(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
00398 }
00399 
00400 
00401 void ap_sta_session_timeout(struct hostapd_data *hapd, struct sta_info *sta,
00402                             u32 session_timeout)
00403 {
00404         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
00405                        HOSTAPD_LEVEL_DEBUG, "setting session timeout to %d "
00406                        "seconds", session_timeout);
00407         eloop_cancel_timeout(ap_handle_session_timer, hapd, sta);
00408         eloop_register_timeout(session_timeout, 0, ap_handle_session_timer,
00409                                hapd, sta);
00410 }
00411 
00412 
00413 void ap_sta_no_session_timeout(struct hostapd_data *hapd, struct sta_info *sta)
00414 {
00415         eloop_cancel_timeout(ap_handle_session_timer, hapd, sta);
00416 }
00417 
00418 
00419 struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr)
00420 {
00421         struct sta_info *sta;
00422 
00423         sta = ap_get_sta(hapd, addr);
00424         if (sta)
00425                 return sta;
00426 
00427         wpa_printf(MSG_DEBUG, "  New STA");
00428         if (hapd->num_sta >= hapd->conf->max_num_sta) {
00429                 /* FIX: might try to remove some old STAs first? */
00430                 wpa_printf(MSG_DEBUG, "no more room for new STAs (%d/%d)",
00431                            hapd->num_sta, hapd->conf->max_num_sta);
00432                 return NULL;
00433         }
00434 
00435         sta = os_zalloc(sizeof(struct sta_info));
00436         if (sta == NULL) {
00437                 wpa_printf(MSG_ERROR, "malloc failed");
00438                 return NULL;
00439         }
00440         sta->acct_interim_interval = hapd->conf->radius->acct_interim_interval;
00441 
00442         /* initialize STA info data */
00443         eloop_register_timeout(hapd->conf->ap_max_inactivity, 0,
00444                                ap_handle_timer, hapd, sta);
00445         os_memcpy(sta->addr, addr, ETH_ALEN);
00446         sta->next = hapd->sta_list;
00447         hapd->sta_list = sta;
00448         hapd->num_sta++;
00449         ap_sta_hash_add(hapd, sta);
00450         sta->ssid = &hapd->conf->ssid;
00451 
00452         return sta;
00453 }
00454 
00455 
00456 static int ap_sta_remove(struct hostapd_data *hapd, struct sta_info *sta)
00457 {
00458         ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
00459 
00460         wpa_printf(MSG_DEBUG, "Removing STA " MACSTR " from kernel driver",
00461                    MAC2STR(sta->addr));
00462         if (hostapd_sta_remove(hapd, sta->addr) &&
00463             sta->flags & WLAN_STA_ASSOC) {
00464                 wpa_printf(MSG_DEBUG, "Could not remove station " MACSTR
00465                            " from kernel driver.", MAC2STR(sta->addr));
00466                 return -1;
00467         }
00468         return 0;
00469 }
00470 
00471 
00472 static int ap_sta_in_other_bss(struct hostapd_data *hapd,
00473                                struct sta_info *sta, u32 flags)
00474 {
00475         struct hostapd_iface *iface = hapd->iface;
00476         size_t i;
00477 
00478         for (i = 0; i < iface->num_bss; i++) {
00479                 struct hostapd_data *bss = iface->bss[i];
00480                 struct sta_info *sta2;
00481                 /* bss should always be set during operation, but it may be
00482                  * NULL during reconfiguration. Assume the STA is not
00483                  * associated to another BSS in that case to avoid NULL pointer
00484                  * dereferences. */
00485                 if (bss == hapd || bss == NULL)
00486                         continue;
00487                 sta2 = ap_get_sta(bss, sta->addr);
00488                 if (sta2 && ((sta2->flags & flags) == flags))
00489                         return 1;
00490         }
00491 
00492         return 0;
00493 }
00494 
00495 
00496 void ap_sta_disassociate(struct hostapd_data *hapd, struct sta_info *sta,
00497                          u16 reason)
00498 {
00499         wpa_printf(MSG_DEBUG, "%s: disassociate STA " MACSTR,
00500                    hapd->conf->iface, MAC2STR(sta->addr));
00501         sta->flags &= ~WLAN_STA_ASSOC;
00502         if (!ap_sta_in_other_bss(hapd, sta, WLAN_STA_ASSOC))
00503                 ap_sta_remove(hapd, sta);
00504         sta->timeout_next = STA_DEAUTH;
00505         eloop_cancel_timeout(ap_handle_timer, hapd, sta);
00506         eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DISASSOC, 0,
00507                                ap_handle_timer, hapd, sta);
00508         accounting_sta_stop(hapd, sta);
00509         ieee802_1x_free_station(sta);
00510 
00511         mlme_disassociate_indication(hapd, sta, reason);
00512 }
00513 
00514 
00515 void ap_sta_deauthenticate(struct hostapd_data *hapd, struct sta_info *sta,
00516                            u16 reason)
00517 {
00518         wpa_printf(MSG_DEBUG, "%s: deauthenticate STA " MACSTR,
00519                    hapd->conf->iface, MAC2STR(sta->addr));
00520         sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
00521         if (!ap_sta_in_other_bss(hapd, sta, WLAN_STA_ASSOC))
00522                 ap_sta_remove(hapd, sta);
00523         sta->timeout_next = STA_REMOVE;
00524         eloop_cancel_timeout(ap_handle_timer, hapd, sta);
00525         eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DEAUTH, 0,
00526                                ap_handle_timer, hapd, sta);
00527         accounting_sta_stop(hapd, sta);
00528         ieee802_1x_free_station(sta);
00529 
00530         mlme_deauthenticate_indication(hapd, sta, reason);
00531 }
00532 
00533 
00534 int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta,
00535                      int old_vlanid)
00536 {
00537 #ifndef CONFIG_NO_VLAN
00538         const char *iface;
00539         struct hostapd_vlan *vlan = NULL;
00540 
00541         /*
00542          * Do not proceed furthur if the vlan id remains same. We do not want
00543          * duplicate dynamic vlan entries.
00544          */
00545         if (sta->vlan_id == old_vlanid)
00546                 return 0;
00547 
00548         /*
00549          * During 1x reauth, if the vlan id changes, then remove the old id and
00550          * proceed furthur to add the new one.
00551          */
00552         if (old_vlanid > 0)
00553                 vlan_remove_dynamic(hapd, old_vlanid);
00554 
00555         iface = hapd->conf->iface;
00556         if (sta->ssid->vlan[0])
00557                 iface = sta->ssid->vlan;
00558 
00559         if (sta->ssid->dynamic_vlan == DYNAMIC_VLAN_DISABLED)
00560                 sta->vlan_id = 0;
00561         else if (sta->vlan_id > 0) {
00562                 vlan = hapd->conf->vlan;
00563                 while (vlan) {
00564                         if (vlan->vlan_id == sta->vlan_id ||
00565                             vlan->vlan_id == VLAN_ID_WILDCARD) {
00566                                 iface = vlan->ifname;
00567                                 break;
00568                         }
00569                         vlan = vlan->next;
00570                 }
00571         }
00572 
00573         if (sta->vlan_id > 0 && vlan == NULL) {
00574                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
00575                                HOSTAPD_LEVEL_DEBUG, "could not find VLAN for "
00576                                "binding station to (vlan_id=%d)",
00577                                sta->vlan_id);
00578                 return -1;
00579         } else if (sta->vlan_id > 0 && vlan->vlan_id == VLAN_ID_WILDCARD) {
00580                 vlan = vlan_add_dynamic(hapd, vlan, sta->vlan_id);
00581                 if (vlan == NULL) {
00582                         hostapd_logger(hapd, sta->addr,
00583                                        HOSTAPD_MODULE_IEEE80211,
00584                                        HOSTAPD_LEVEL_DEBUG, "could not add "
00585                                        "dynamic VLAN interface for vlan_id=%d",
00586                                        sta->vlan_id);
00587                         return -1;
00588                 }
00589 
00590                 iface = vlan->ifname;
00591                 if (vlan_setup_encryption_dyn(hapd, sta->ssid, iface) != 0) {
00592                         hostapd_logger(hapd, sta->addr,
00593                                        HOSTAPD_MODULE_IEEE80211,
00594                                        HOSTAPD_LEVEL_DEBUG, "could not "
00595                                        "configure encryption for dynamic VLAN "
00596                                        "interface for vlan_id=%d",
00597                                        sta->vlan_id);
00598                 }
00599 
00600                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
00601                                HOSTAPD_LEVEL_DEBUG, "added new dynamic VLAN "
00602                                "interface '%s'", iface);
00603         } else if (vlan && vlan->vlan_id == sta->vlan_id) {
00604                 if (sta->vlan_id > 0) {
00605                         vlan->dynamic_vlan++;
00606                         hostapd_logger(hapd, sta->addr,
00607                                        HOSTAPD_MODULE_IEEE80211,
00608                                        HOSTAPD_LEVEL_DEBUG, "updated existing "
00609                                        "dynamic VLAN interface '%s'", iface);
00610                 }
00611 
00612                 /*
00613                  * Update encryption configuration for statically generated
00614                  * VLAN interface. This is only used for static WEP
00615                  * configuration for the case where hostapd did not yet know
00616                  * which keys are to be used when the interface was added.
00617                  */
00618                 if (vlan_setup_encryption_dyn(hapd, sta->ssid, iface) != 0) {
00619                         hostapd_logger(hapd, sta->addr,
00620                                        HOSTAPD_MODULE_IEEE80211,
00621                                        HOSTAPD_LEVEL_DEBUG, "could not "
00622                                        "configure encryption for VLAN "
00623                                        "interface for vlan_id=%d",
00624                                        sta->vlan_id);
00625                 }
00626         }
00627 
00628         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
00629                        HOSTAPD_LEVEL_DEBUG, "binding station to interface "
00630                        "'%s'", iface);
00631 
00632         if (wpa_auth_sta_set_vlan(sta->wpa_sm, sta->vlan_id) < 0)
00633                 wpa_printf(MSG_INFO, "Failed to update VLAN-ID for WPA");
00634 
00635         return hostapd_set_sta_vlan(iface, hapd, sta->addr, sta->vlan_id);
00636 #else /* CONFIG_NO_VLAN */
00637         return 0;
00638 #endif /* CONFIG_NO_VLAN */
00639 }
00640 
00641 
00642 #ifdef CONFIG_IEEE80211W
00643 
00644 int ap_check_sa_query_timeout(struct hostapd_data *hapd, struct sta_info *sta)
00645 {
00646         u32 tu;
00647         struct os_time now, passed;
00648         os_get_time(&now);
00649         os_time_sub(&now, &sta->sa_query_start, &passed);
00650         tu = (passed.sec * 1000000 + passed.usec) / 1024;
00651         if (hapd->conf->assoc_sa_query_max_timeout < tu) {
00652                 hostapd_logger(hapd, sta->addr,
00653                                HOSTAPD_MODULE_IEEE80211,
00654                                HOSTAPD_LEVEL_DEBUG,
00655                                "association SA Query timed out");
00656                 sta->sa_query_timed_out = 1;
00657                 os_free(sta->sa_query_trans_id);
00658                 sta->sa_query_trans_id = NULL;
00659                 sta->sa_query_count = 0;
00660                 eloop_cancel_timeout(ap_sa_query_timer, hapd, sta);
00661                 return 1;
00662         }
00663 
00664         return 0;
00665 }
00666 
00667 
00668 static void ap_sa_query_timer(void *eloop_ctx, void *timeout_ctx)
00669 {
00670         struct hostapd_data *hapd = eloop_ctx;
00671         struct sta_info *sta = timeout_ctx;
00672         unsigned int timeout, sec, usec;
00673         u8 *trans_id, *nbuf;
00674 
00675         if (sta->sa_query_count > 0 &&
00676             ap_check_sa_query_timeout(hapd, sta))
00677                 return;
00678 
00679         nbuf = os_realloc(sta->sa_query_trans_id,
00680                           (sta->sa_query_count + 1) * WLAN_SA_QUERY_TR_ID_LEN);
00681         if (nbuf == NULL)
00682                 return;
00683         if (sta->sa_query_count == 0) {
00684                 /* Starting a new SA Query procedure */
00685                 os_get_time(&sta->sa_query_start);
00686         }
00687         trans_id = nbuf + sta->sa_query_count * WLAN_SA_QUERY_TR_ID_LEN;
00688         sta->sa_query_trans_id = nbuf;
00689         sta->sa_query_count++;
00690 
00691         os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN);
00692 
00693         timeout = hapd->conf->assoc_sa_query_retry_timeout;
00694         sec = ((timeout / 1000) * 1024) / 1000;
00695         usec = (timeout % 1000) * 1024;
00696         eloop_register_timeout(sec, usec, ap_sa_query_timer, hapd, sta);
00697 
00698         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
00699                        HOSTAPD_LEVEL_DEBUG,
00700                        "association SA Query attempt %d", sta->sa_query_count);
00701 
00702 #ifdef NEED_AP_MLME
00703         ieee802_11_send_sa_query_req(hapd, sta->addr, trans_id);
00704 #endif /* NEED_AP_MLME */
00705 }
00706 
00707 
00708 void ap_sta_start_sa_query(struct hostapd_data *hapd, struct sta_info *sta)
00709 {
00710         ap_sa_query_timer(hapd, sta);
00711 }
00712 
00713 
00714 void ap_sta_stop_sa_query(struct hostapd_data *hapd, struct sta_info *sta)
00715 {
00716         eloop_cancel_timeout(ap_sa_query_timer, hapd, sta);
00717         os_free(sta->sa_query_trans_id);
00718         sta->sa_query_trans_id = NULL;
00719         sta->sa_query_count = 0;
00720 }
00721 
00722 #endif /* CONFIG_IEEE80211W */
00723 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on Sat Nov 21 23:16:48 2009 for hostapd by  doxygen 1.6.1