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;
}
Esempio n. 2
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;
}
Esempio n. 3
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;
}
Esempio n. 4
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)
	{
		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;
}
Esempio n. 5
0
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;
}
Esempio n. 6
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;
}
Esempio n. 7
0
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;
    }
}