static int hostapd_ctrl_iface_new_sta(struct hostapd_data *hapd, const char *txtaddr) { u8 addr[ETH_ALEN]; struct sta_info *sta; wpa_printf(MSG_DEBUG, "CTRL_IFACE NEW_STA %s", txtaddr); if (hwaddr_aton(txtaddr, addr)) return -1; sta = ap_get_sta(hapd, addr); if (sta) return 0; wpa_printf(MSG_DEBUG, "Add new STA " MACSTR " based on ctrl_iface " "notification", MAC2STR(addr)); sta = ap_sta_add(hapd, addr); if (sta == NULL) return -1; hostapd_new_assoc_sta(hapd, sta, 0); accounting_sta_get_id(hapd, sta); return 0; }
static int test_driver_new_sta(struct test_driver_data *drv, struct test_driver_bss *bss, const u8 *addr, const u8 *ie, size_t ielen) { struct hostapd_data *hapd; struct sta_info *sta; int new_assoc, res; hapd = test_driver_get_hapd(drv, bss); if (hapd == NULL) return -1; hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "associated"); sta = ap_get_sta(hapd, addr); if (sta) { accounting_sta_stop(hapd, sta); } else { sta = ap_sta_add(hapd, addr); if (sta == NULL) return -1; } accounting_sta_get_id(hapd, sta); if (hapd->conf->wpa) { if (ie == NULL || ielen == 0) { printf("test_driver: no IE from STA\n"); return -1; } if (sta->wpa_sm == NULL) sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, sta->addr); if (sta->wpa_sm == NULL) { printf("test_driver: Failed to initialize WPA state " "machine\n"); return -1; } res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, ie, ielen); if (res != WPA_IE_OK) { printf("WPA/RSN information element rejected? " "(res %u)\n", res); return -1; } } new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0; sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC; wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC); hostapd_new_assoc_sta(hapd, sta, !new_assoc); ieee802_1x_notify_port_enabled(sta->eapol_sm, 1); return 0; }
struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr) { struct sta_info *sta; sta = ap_get_sta(hapd, addr); if (sta) return sta; wpa_printf(MSG_DEBUG, " New STA"); if (hapd->num_sta >= hapd->conf->max_num_sta) { /* FIX: might try to remove some old STAs first? */ wpa_printf(MSG_DEBUG, "no more room for new STAs (%d/%d)", hapd->num_sta, hapd->conf->max_num_sta); return NULL; } sta = os_zalloc(sizeof(struct sta_info)); if (sta == NULL) { wpa_printf(MSG_ERROR, "malloc failed"); return NULL; } sta->acct_interim_interval = hapd->conf->acct_interim_interval; if (accounting_sta_get_id(hapd, sta) < 0) { os_free(sta); return NULL; } if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_INACTIVITY_TIMER)) { wpa_printf(MSG_DEBUG, "%s: register ap_handle_timer timeout " "for " MACSTR " (%d seconds - ap_max_inactivity)", __func__, MAC2STR(addr), hapd->conf->ap_max_inactivity); eloop_register_timeout(hapd->conf->ap_max_inactivity, 0, ap_handle_timer, hapd, sta); } /* initialize STA info data */ os_memcpy(sta->addr, addr, ETH_ALEN); sta->next = hapd->sta_list; hapd->sta_list = sta; hapd->num_sta++; ap_sta_hash_add(hapd, sta); ap_sta_remove_in_other_bss(hapd, sta); sta->last_seq_ctrl = WLAN_INVALID_MGMT_SEQ; dl_list_init(&sta->ip6addr); #ifdef CONFIG_TAXONOMY sta_track_claim_taxonomy_info(hapd->iface, addr, &sta->probe_ie_taxonomy); #endif /* CONFIG_TAXONOMY */ return sta; }
struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr) { struct sta_info *sta; sta = ap_get_sta(hapd, addr); if (sta) { printf("sta exists\n"); return sta; } wpa_printf(MSG_DEBUG, " New STA"); printf("New Sta\n"); if (hapd->num_sta >= hapd->conf->max_num_sta) { /* FIX: might try to remove some old STAs first? */ wpa_printf(MSG_DEBUG, "no more room for new STAs (%d/%d)",hapd->num_sta, hapd->conf->max_num_sta); printf("Space problem\n"); return NULL; } sta = os_zalloc(sizeof(struct sta_info)); if (sta == NULL) { wpa_printf(MSG_ERROR, "malloc failed"); printf("malloc problem\n"); return NULL; } sta->acct_interim_interval = hapd->conf->acct_interim_interval; accounting_sta_get_id(hapd, sta); /* initialize STA info data */ wpa_printf(MSG_DEBUG, "%s: register ap_handle_timer timeout " "for " MACSTR " (%d seconds - ap_max_inactivity)", __func__, MAC2STR(addr), hapd->conf->ap_max_inactivity); eloop_register_timeout(hapd->conf->ap_max_inactivity, 0, ap_handle_timer, hapd, sta); os_memcpy(sta->addr, addr, ETH_ALEN); sta->next = hapd->sta_list; hapd->sta_list = sta; hapd->num_sta++; ap_sta_hash_add(hapd, sta); sta->ssid = &hapd->conf->ssid; ap_sta_remove_in_other_bss(hapd, sta); printf("Sta added!!\n"); return sta; }
static int madwifi_new_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) { struct hostapd_data *hapd = drv->hapd; struct sta_info *sta; int new_assoc; hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "associated"); sta = ap_get_sta(hapd, addr); if (sta) { accounting_sta_stop(hapd, sta); } else { sta = ap_sta_add(hapd, addr); if (sta == NULL) return -1; } if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) { /* Cached accounting data is not valid anymore. */ memset(drv->acct_mac, 0, ETH_ALEN); memset(&drv->acct_data, 0, sizeof(drv->acct_data)); } accounting_sta_get_id(hapd, sta); if (hapd->conf->wpa) { if (madwifi_process_wpa_ie(drv, sta)) return -1; } /* * Now that the internal station state is setup * kick the authenticator into action. */ new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0; sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC; wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC); hostapd_new_assoc_sta(hapd, sta, !new_assoc); ieee802_1x_notify_port_enabled(sta->eapol_sm, 1); return 0; }
/** * accounting_sta_start - Start STA accounting * @hapd: hostapd BSS data * @sta: The station */ void accounting_sta_start(struct hostapd_data *hapd, struct sta_info *sta) { struct radius_msg *msg; struct os_time t; int interval; if (sta->acct_session_started) return; accounting_sta_get_id(hapd, sta); hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS, HOSTAPD_LEVEL_INFO, "starting accounting session %08X-%08X", sta->acct_session_id_hi, sta->acct_session_id_lo); //Tymon added for accounting.c capwap_printf(hapd, sta->addr, STA_CONNECTED); os_get_time(&t); sta->acct_session_start = t.sec; sta->last_rx_bytes = sta->last_tx_bytes = 0; sta->acct_input_gigawords = sta->acct_output_gigawords = 0; hostapd_drv_sta_clear_stats(hapd, sta->addr); if (!hapd->conf->radius->acct_server) return; if (sta->acct_interim_interval) interval = sta->acct_interim_interval; else interval = ACCT_DEFAULT_UPDATE_INTERVAL; eloop_register_timeout(interval, 0, accounting_interim_update, hapd, sta); msg = accounting_msg(hapd, sta, RADIUS_ACCT_STATUS_TYPE_START); if (msg && radius_client_send(hapd->radius, msg, RADIUS_ACCT, sta->addr) < 0) radius_msg_free(msg); sta->acct_session_started = 1; }
static void handle_assoc_cb(hostapd *hapd, struct ieee80211_mgmt *mgmt, size_t len, int reassoc, int ok) { u16 status; struct sta_info *sta; int new_assoc = 1; if (!ok) { hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "did not acknowledge association response"); return; } if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) : sizeof(mgmt->u.assoc_req))) { printf("handle_assoc_cb(reassoc=%d) - too short payload " "(len=%lu)\n", reassoc, (unsigned long) len); return; } if (reassoc) status = le_to_host16(mgmt->u.reassoc_resp.status_code); else status = le_to_host16(mgmt->u.assoc_resp.status_code); sta = ap_get_sta(hapd, mgmt->da); if (!sta) { printf("handle_assoc_cb: STA " MACSTR " not found\n", MAC2STR(mgmt->da)); return; } if (status != WLAN_STATUS_SUCCESS) goto fail; /* Stop previous accounting session, if one is started, and allocate * new session id for the new session. */ accounting_sta_stop(hapd, sta); accounting_sta_get_id(hapd, sta); hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "associated (aid %d, accounting session %08X-%08X)", sta->aid, sta->acct_session_id_hi, sta->acct_session_id_lo); if (sta->flags & WLAN_STA_ASSOC) new_assoc = 0; sta->flags |= WLAN_STA_ASSOC; if (hostapd_sta_add(hapd, sta->addr, sta->aid, sta->capability, sta->tx_supp_rates)) { printf("Could not add station to kernel driver.\n"); } wpa_sm_event(hapd, sta, WPA_ASSOC); hostapd_new_assoc_sta(hapd, sta, !new_assoc); ieee802_1x_notify_port_enabled(sta->eapol_sm, 1); fail: /* Copy of the association request is not needed anymore */ if (sta->last_assoc_req) { free(sta->last_assoc_req); sta->last_assoc_req = NULL; } }