Beispiel #1
0
static int ctrl_inject_auth(struct wlantest *wt, struct wlantest_bss *bss,
			    struct wlantest_sta *sta, int sender_ap,
			    enum wlantest_inject_protection prot)
{
	struct ieee80211_mgmt mgmt;

	if (prot != WLANTEST_INJECT_NORMAL &&
	    prot != WLANTEST_INJECT_UNPROTECTED)
		return -1; /* Authentication frame is never protected */
	if (sta == NULL)
		return -1; /* No broadcast Authentication frames */

	if (sender_ap)
		wpa_printf(MSG_INFO, "INJECT: Auth " MACSTR " -> " MACSTR,
			   MAC2STR(bss->bssid), MAC2STR(sta->addr));
	else
		wpa_printf(MSG_INFO, "INJECT: Auth " MACSTR " -> " MACSTR,
			   MAC2STR(sta->addr), MAC2STR(bss->bssid));
	build_mgmt_hdr(&mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_AUTH);

	mgmt.u.auth.auth_alg = host_to_le16(WLAN_AUTH_OPEN);
	mgmt.u.auth.auth_transaction = host_to_le16(1);
	mgmt.u.auth.status_code = host_to_le16(WLAN_STATUS_SUCCESS);

	return wlantest_inject(wt, bss, sta, (u8 *) &mgmt, 24 + 6,
			       WLANTEST_INJECT_UNPROTECTED);
}
static int hostapd_header_beacon(packet_element_t* p, u8* macaddr, u16 beacon_period)
{
    struct ieee80211_mgmt* head=NULL;
    p->len = (u8)(int)&(head->u.beacon.variable[0]);
    head = (struct ieee80211_mgmt*)malloc(p->len);

    // FRAME CONTROL (2) : PROTOCOL=0 + TYPE=MNGT + SUBTYPE=BEACON, FROMDS, TODS....
    head->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_BEACON);
    // FRAME DURATION (2) : 0 (typic for broadcast/multicast)
    head->duration = host_to_le16(0);
    // ADDR1 (6) = DA ( destination = broadcast)
    memcpy(head->da, broadcast_ether_addr, ETH_ALEN);
    // ADDR2 (6) = SA ( source = me)
    memcpy(head->sa, macaddr, ETH_ALEN);
    // ADDR3 (6) = BSSID ( me)
    memcpy(head->bssid, macaddr, ETH_ALEN);
    // SEQUENCE-CTRL (2)
    head->seq_ctrl = host_to_le16(0);

    // FRAME BODY FIXED ELEMENTS FOR BEACON
    // BEACON TIMESTAMP (8)
    memset(head->u.beacon.timestamp, 0, sizeof(head->u.beacon.timestamp)); //set by PHY ?
    // BEACON INTERVAL (2)
    head->u.beacon.beacon_int = host_to_le16(beacon_period);
    // BEACON CAPA (2)
    head->u.beacon.capab_info = host_to_le16(0x401); // TODO: check capabilities
    p->d = (u8*)head;
    return p->len;
}
Beispiel #3
0
static void ieee802_11_sta_authenticate(void *eloop_ctx, void *timeout_ctx)
{
    hostapd *hapd = eloop_ctx;
    struct ieee80211_mgmt mgmt;

    if (hapd->assoc_ap_state == WAIT_BEACON)
        hapd->assoc_ap_state = AUTHENTICATE;
    if (hapd->assoc_ap_state != AUTHENTICATE)
        return;

    printf("Authenticate with AP " MACSTR " SSID=",
           MAC2STR(hapd->conf->assoc_ap_addr));
    ieee802_11_print_ssid((u8 *) hapd->assoc_ap_ssid,
                          hapd->assoc_ap_ssid_len);
    printf(" (as station)\n");

    memset(&mgmt, 0, sizeof(mgmt));
    mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
                                      WLAN_FC_STYPE_AUTH);
    /* Request TX callback */
    mgmt.frame_control |= host_to_le16(BIT(1));
    memcpy(mgmt.da, hapd->conf->assoc_ap_addr, ETH_ALEN);
    memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
    memcpy(mgmt.bssid, hapd->conf->assoc_ap_addr, ETH_ALEN);
    mgmt.u.auth.auth_alg = host_to_le16(WLAN_AUTH_OPEN);
    mgmt.u.auth.auth_transaction = host_to_le16(1);
    mgmt.u.auth.status_code = host_to_le16(0);
    if (hostapd_send_mgmt_frame(hapd, &mgmt, IEEE80211_HDRLEN +
                                sizeof(mgmt.u.auth), 0) < 0)
        perror("ieee802_11_sta_authenticate: send");

    /* Try to authenticate again, if this attempt fails or times out. */
    eloop_register_timeout(5, 0, ieee802_11_sta_authenticate, hapd, NULL);
}
static int ibss_rsn_send_auth(struct ibss_rsn *ibss_rsn, const u8 *da, int seq)
{
	struct ieee80211_mgmt auth;
	const size_t auth_length = IEEE80211_HDRLEN + sizeof(auth.u.auth);
	struct wpa_supplicant *wpa_s = ibss_rsn->wpa_s;

	if (wpa_s->driver->send_frame == NULL)
		return -1;

	os_memset(&auth, 0, sizeof(auth));

	auth.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
					  WLAN_FC_STYPE_AUTH);
	os_memcpy(auth.da, da, ETH_ALEN);
	os_memcpy(auth.sa, wpa_s->own_addr, ETH_ALEN);
	os_memcpy(auth.bssid, wpa_s->bssid, ETH_ALEN);

	auth.u.auth.auth_alg = host_to_le16(WLAN_AUTH_OPEN);
	auth.u.auth.auth_transaction = host_to_le16(seq);
	auth.u.auth.status_code = host_to_le16(WLAN_STATUS_SUCCESS);

	wpa_printf(MSG_DEBUG, "RSN: IBSS TX Auth frame (SEQ %d) to " MACSTR,
		   seq, MAC2STR(da));

	return wpa_s->driver->send_frame(wpa_s->drv_priv, (u8 *) &auth,
					 auth_length, 0);
}
Beispiel #5
0
static void wpa_ft_generate_pmk_r1(struct wpa_authenticator *wpa_auth,
				   struct wpa_ft_pmk_r0_sa *pmk_r0,
				   struct ft_remote_r1kh *r1kh,
				   const u8 *s1kh_id, int pairwise)
{
	struct ft_r0kh_r1kh_push_frame frame, f;
	struct os_time now;

	os_memset(&frame, 0, sizeof(frame));
	frame.frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB;
	frame.packet_type = FT_PACKET_R0KH_R1KH_PUSH;
	frame.data_length = host_to_le16(FT_R0KH_R1KH_PUSH_DATA_LEN);
	os_memcpy(frame.ap_address, wpa_auth->addr, ETH_ALEN);

	/* aes_wrap() does not support inplace encryption, so use a temporary
	 * buffer for the data. */
	os_memcpy(f.r1kh_id, r1kh->id, FT_R1KH_ID_LEN);
	os_memcpy(f.s1kh_id, s1kh_id, ETH_ALEN);
	os_memcpy(f.pmk_r0_name, pmk_r0->pmk_r0_name, WPA_PMK_NAME_LEN);
	wpa_derive_pmk_r1(pmk_r0->pmk_r0, pmk_r0->pmk_r0_name, r1kh->id,
			  s1kh_id, f.pmk_r1, f.pmk_r1_name);
	wpa_printf(MSG_DEBUG, "FT: R1KH-ID " MACSTR, MAC2STR(r1kh->id));
	wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", f.pmk_r1, PMK_LEN);
	wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", f.pmk_r1_name,
		    WPA_PMK_NAME_LEN);
	os_get_time(&now);
	WPA_PUT_LE32(f.timestamp, now.sec);
	f.pairwise = host_to_le16(pairwise);
	if (aes_wrap(r1kh->key, (FT_R0KH_R1KH_PUSH_DATA_LEN + 7) / 8,
		     f.timestamp, frame.timestamp) < 0)
		return;

	wpa_ft_rrb_send(wpa_auth, r1kh->addr, (u8 *) &frame, sizeof(frame));
}
Beispiel #6
0
/* derive mesh temporal key from pmk */
int mesh_rsn_derive_mtk(struct wpa_supplicant *wpa_s, struct sta_info *sta)
{
	u8 *ptr;
	u8 *min, *max;
	u16 min_lid, max_lid;
	size_t nonce_len = sizeof(sta->my_nonce);
	size_t lid_len = sizeof(sta->my_lid);
	u8 *myaddr = wpa_s->own_addr;
	u8 *peer = sta->addr;
	/* 2 nonces, 2 linkids, akm suite, 2 mac addrs */
	u8 context[64 + 4 + 4 + 12];

	ptr = context;
	if (os_memcmp(sta->my_nonce, sta->peer_nonce, nonce_len) < 0) {
		min = sta->my_nonce;
		max = sta->peer_nonce;
	} else {
		min = sta->peer_nonce;
		max = sta->my_nonce;
	}
	os_memcpy(ptr, min, nonce_len);
	os_memcpy(ptr + nonce_len, max, nonce_len);
	ptr += 2 * nonce_len;

	if (sta->my_lid < sta->peer_lid) {
		min_lid = host_to_le16(sta->my_lid);
		max_lid = host_to_le16(sta->peer_lid);
	} else {
		min_lid = host_to_le16(sta->peer_lid);
		max_lid = host_to_le16(sta->my_lid);
	}
	os_memcpy(ptr, &min_lid, lid_len);
	os_memcpy(ptr + lid_len, &max_lid, lid_len);
	ptr += 2 * lid_len;

	/* SAE */
	RSN_SELECTOR_PUT(ptr, wpa_cipher_to_suite(0, WPA_CIPHER_GCMP));
	ptr += 4;

	if (os_memcmp(myaddr, peer, ETH_ALEN) < 0) {
		min = myaddr;
		max = peer;
	} else {
		min = peer;
		max = myaddr;
	}
	os_memcpy(ptr, min, ETH_ALEN);
	os_memcpy(ptr + ETH_ALEN, max, ETH_ALEN);

	sha256_prf(sta->sae->pmk, sizeof(sta->sae->pmk),
		   "Temporal Key Derivation", context, sizeof(context),
		   sta->mtk, sizeof(sta->mtk));
	return 0;
}
Beispiel #7
0
static struct wmm_ac_addts_request *
wmm_ac_build_addts_req(struct wpa_supplicant *wpa_s,
		       const struct wmm_ac_ts_setup_params *params,
		       const u8 *address)
{
	struct wmm_ac_addts_request *addts_req;
	struct wmm_tspec_element *tspec;
	u8 ac = up_to_ac[params->user_priority];
	u8 uapsd = wpa_s->wmm_ac_assoc_info->ac_params[ac].uapsd;

	addts_req = os_zalloc(sizeof(*addts_req));
	if (!addts_req)
		return NULL;

	tspec = &addts_req->tspec;
	os_memcpy(addts_req->address, address, ETH_ALEN);

	/* The dialog token cannot be zero */
	if (++wpa_s->wmm_ac_last_dialog_token == 0)
		wpa_s->wmm_ac_last_dialog_token++;

	addts_req->dialog_token = wpa_s->wmm_ac_last_dialog_token;
	tspec->eid = WLAN_EID_VENDOR_SPECIFIC;
	tspec->length = sizeof(*tspec) - 2; /* reduce eid and length */
	tspec->oui[0] = 0x00;
	tspec->oui[1] = 0x50;
	tspec->oui[2] = 0xf2;
	tspec->oui_type = WMM_OUI_TYPE;
	tspec->oui_subtype = WMM_OUI_SUBTYPE_TSPEC_ELEMENT;
	tspec->version = WMM_VERSION;

	tspec->ts_info[0] = params->tsid << 1;
	tspec->ts_info[0] |= params->direction << 5;
	tspec->ts_info[0] |= WMM_AC_ACCESS_POLICY_EDCA << 7;
	tspec->ts_info[1] = uapsd << 2;
	tspec->ts_info[1] |= params->user_priority << 3;
	tspec->ts_info[2] = 0;

	tspec->nominal_msdu_size = host_to_le16(params->nominal_msdu_size);
	if (params->fixed_nominal_msdu)
		tspec->nominal_msdu_size |=
			host_to_le16(WMM_AC_FIXED_MSDU_SIZE);

	tspec->mean_data_rate = host_to_le32(params->mean_data_rate);
	tspec->minimum_phy_rate = host_to_le32(params->minimum_phy_rate);
	tspec->surplus_bandwidth_allowance =
		host_to_le16(params->surplus_bandwidth_allowance);

	return addts_req;
}
static int p2p_manager_disconnect(struct hostapd_data *hapd, u16 stype,
				  u8 minor_reason_code, const u8 *addr)
{
	struct ieee80211_mgmt *mgmt;
	int ret;
	u8 *pos;

	if (hapd->driver->send_frame == NULL)
		return -1;

	mgmt = os_zalloc(sizeof(*mgmt) + 100);
	if (mgmt == NULL)
		return -1;

	mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, stype);
	wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "P2P: Disconnect STA " MACSTR
		" with minor reason code %u (stype=%u (%s))",
		MAC2STR(addr), minor_reason_code, stype,
		fc2str(mgmt->frame_control));

	os_memcpy(mgmt->da, addr, ETH_ALEN);
	os_memcpy(mgmt->sa, hapd->own_addr, ETH_ALEN);
	os_memcpy(mgmt->bssid, hapd->own_addr, ETH_ALEN);
	if (stype == WLAN_FC_STYPE_DEAUTH) {
		mgmt->u.deauth.reason_code =
			host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
		pos = (u8 *) (&mgmt->u.deauth.reason_code + 1);
	} else {
		mgmt->u.disassoc.reason_code =
			host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
		pos = (u8 *) (&mgmt->u.disassoc.reason_code + 1);
	}

	*pos++ = WLAN_EID_VENDOR_SPECIFIC;
	*pos++ = 4 + 3 + 1;
	WPA_PUT_BE32(pos, P2P_IE_VENDOR_TYPE);
	pos += 4;

	*pos++ = P2P_ATTR_MINOR_REASON_CODE;
	WPA_PUT_LE16(pos, 1);
	pos += 2;
	*pos++ = minor_reason_code;

	ret = hapd->driver->send_frame(hapd->drv_priv, (u8 *) mgmt,
				       pos - (u8 *) mgmt, 1);
	os_free(mgmt);

	return ret < 0 ? -1 : 0;
}
Beispiel #9
0
void
mwrite16(struct memfile *mf, int16_t value)
{
    int16_t le_value = host_to_le16(value);

    mwrite(mf, &le_value, 2);
}
int wnm_send_disassoc_imminent(struct hostapd_data *hapd,
			       struct sta_info *sta, int disassoc_timer)
{
	u8 buf[1000], *pos;
	struct ieee80211_mgmt *mgmt;

	os_memset(buf, 0, sizeof(buf));
	mgmt = (struct ieee80211_mgmt *) buf;
	mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
					   WLAN_FC_STYPE_ACTION);
	os_memcpy(mgmt->da, sta->addr, ETH_ALEN);
	os_memcpy(mgmt->sa, hapd->own_addr, ETH_ALEN);
	os_memcpy(mgmt->bssid, hapd->own_addr, ETH_ALEN);
	mgmt->u.action.category = WLAN_ACTION_WNM;
	mgmt->u.action.u.bss_tm_req.action = WNM_BSS_TRANS_MGMT_REQ;
	mgmt->u.action.u.bss_tm_req.dialog_token = 1;
	mgmt->u.action.u.bss_tm_req.req_mode =
		WNM_BSS_TM_REQ_DISASSOC_IMMINENT;
	mgmt->u.action.u.bss_tm_req.disassoc_timer =
		host_to_le16(disassoc_timer);
	mgmt->u.action.u.bss_tm_req.validity_interval = 0;

	pos = mgmt->u.action.u.bss_tm_req.variable;

	wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request frame to indicate imminent disassociation (disassoc_timer=%d) to "
		   MACSTR, disassoc_timer, MAC2STR(sta->addr));
	if (hostapd_drv_send_mlme(hapd, buf, pos - buf, 0, NULL, 0) < 0) {
		wpa_printf(MSG_DEBUG, "Failed to send BSS Transition "
			   "Management Request frame");
		return -1;
	}

	return 0;
}
Beispiel #11
0
static int wpa_ft_rrb_rx_request(struct wpa_authenticator *wpa_auth,
				 const u8 *current_ap, const u8 *sta_addr,
				 const u8 *body, size_t len)
{
	struct wpa_state_machine *sm;
	u16 status;
	u8 *resp_ies, *pos;
	size_t resp_ies_len, rlen;
	struct ft_rrb_frame *frame;

	sm = wpa_ft_add_sta(wpa_auth, sta_addr);
	if (sm == NULL) {
		wpa_printf(MSG_DEBUG, "FT: Failed to add new STA based on "
			   "RRB Request");
		return -1;
	}

	wpa_hexdump(MSG_MSGDUMP, "FT: RRB Request Frame body", body, len);

	status = wpa_ft_process_auth_req(sm, body, len, &resp_ies,
					 &resp_ies_len);

	wpa_printf(MSG_DEBUG, "FT: RRB authentication response: STA=" MACSTR
		   " CurrentAP=" MACSTR " status=%d",
		   MAC2STR(sm->addr), MAC2STR(current_ap), status);
	wpa_hexdump(MSG_DEBUG, "FT: Response IEs", resp_ies, resp_ies_len);

	/* RRB - Forward action frame response to the Current AP */

	/*
	 * data: Category[1] Action[1] STA_Address[6] Target_AP_Address[6]
	 * Status_Code[2] FT Request action frame body[variable]
	 */
	rlen = 2 + 2 * ETH_ALEN + 2 + resp_ies_len;

	frame = os_malloc(sizeof(*frame) + rlen);
	frame->frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB;
	frame->packet_type = FT_PACKET_RESPONSE;
	frame->action_length = host_to_le16(rlen);
	os_memcpy(frame->ap_address, wpa_auth->addr, ETH_ALEN);
	pos = (u8 *) (frame + 1);
	*pos++ = WLAN_ACTION_FT;
	*pos++ = 2; /* Action: Response */
	os_memcpy(pos, sta_addr, ETH_ALEN);
	pos += ETH_ALEN;
	os_memcpy(pos, wpa_auth->addr, ETH_ALEN);
	pos += ETH_ALEN;
	WPA_PUT_LE16(pos, status);
	pos += 2;
	if (resp_ies) {
		os_memcpy(pos, resp_ies, resp_ies_len);
		os_free(resp_ies);
	}

	wpa_ft_rrb_send(wpa_auth, current_ap, (u8 *) frame,
			sizeof(*frame) + rlen);
	os_free(frame);

	return 0;
}
Beispiel #12
0
u8 * hostapd_eid_ht_capabilities(struct hostapd_data *hapd, u8 *eid)
{
	struct ieee80211_ht_capabilities *cap;
	u8 *pos = eid;

	if (!hapd->iconf->ieee80211n || !hapd->iface->current_mode)
		return eid;

	*pos++ = WLAN_EID_HT_CAP;
	*pos++ = sizeof(*cap);

	cap = (struct ieee80211_ht_capabilities *) pos;
	os_memset(cap, 0, sizeof(*cap));
	cap->ht_capabilities_info = host_to_le16(hapd->iconf->ht_capab);
	cap->a_mpdu_params = hapd->iface->current_mode->a_mpdu_params;
	os_memcpy(cap->supported_mcs_set, hapd->iface->current_mode->mcs_set,
		  16);

	/* TODO: ht_extended_capabilities (now fully disabled) */
	/* TODO: tx_bf_capability_info (now fully disabled) */
	/* TODO: asel_capabilities (now fully disabled) */

 	pos += sizeof(*cap);

	return pos;
}
Beispiel #13
0
u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid)
{
	struct ieee80211_ht_operation *oper;
	u8 *pos = eid;

	if (!hapd->iconf->ieee80211n)
		return eid;

	*pos++ = WLAN_EID_HT_OPERATION;
	*pos++ = sizeof(*oper);

	oper = (struct ieee80211_ht_operation *) pos;
	os_memset(oper, 0, sizeof(*oper));

	oper->control_chan = hapd->iconf->channel;
	oper->operation_mode = host_to_le16(hapd->iface->ht_op_mode);
	if (hapd->iconf->secondary_channel == 1)
		oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE |
			HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH;
	if (hapd->iconf->secondary_channel == -1)
		oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW |
			HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH;

	pos += sizeof(*oper);

	return pos;
}
Beispiel #14
0
void hostapd_get_ht_capab(struct hostapd_data *hapd,
			  struct ieee80211_ht_capabilities *ht_cap,
			  struct ieee80211_ht_capabilities *neg_ht_cap)
{
	u16 cap;

	if (ht_cap == NULL)
		return;
	os_memcpy(neg_ht_cap, ht_cap, sizeof(*neg_ht_cap));
	cap = le_to_host16(neg_ht_cap->ht_capabilities_info);

	/*
	 * Mask out HT features we don't support, but don't overwrite
	 * non-symmetric features like STBC and SMPS. Just because
	 * we're not in dynamic SMPS mode the STA might still be.
	 */
	cap &= (hapd->iconf->ht_capab | HT_CAP_INFO_RX_STBC_MASK |
		HT_CAP_INFO_TX_STBC | HT_CAP_INFO_SMPS_MASK);

	/*
	 * STBC needs to be handled specially
	 * if we don't support RX STBC, mask out TX STBC in the STA's HT caps
	 * if we don't support TX STBC, mask out RX STBC in the STA's HT caps
	 */
	if (!(hapd->iconf->ht_capab & HT_CAP_INFO_RX_STBC_MASK))
		cap &= ~HT_CAP_INFO_TX_STBC;
	if (!(hapd->iconf->ht_capab & HT_CAP_INFO_TX_STBC))
		cap &= ~HT_CAP_INFO_RX_STBC_MASK;

	neg_ht_cap->ht_capabilities_info = host_to_le16(cap);
}
Beispiel #15
0
void hostapd_get_ht_capab(struct hostapd_data *hapd,
			  struct ieee80211_ht_capabilities *ht_cap,
			  struct ieee80211_ht_capabilities *neg_ht_cap)
{
	u16 cap;

	if (ht_cap == NULL)
		return;
	os_memcpy(neg_ht_cap, ht_cap, sizeof(*neg_ht_cap));
	cap = le_to_host16(neg_ht_cap->ht_capabilities_info);
	cap &= hapd->iconf->ht_capab;
	cap |= (hapd->iconf->ht_capab & HT_CAP_INFO_SMPS_DISABLED);

	/*
	 * STBC needs to be handled specially
	 * if we don't support RX STBC, mask out TX STBC in the STA's HT caps
	 * if we don't support TX STBC, mask out RX STBC in the STA's HT caps
	 */
	if (!(hapd->iconf->ht_capab & HT_CAP_INFO_RX_STBC_MASK))
		cap &= ~HT_CAP_INFO_TX_STBC;
	if (!(hapd->iconf->ht_capab & HT_CAP_INFO_TX_STBC))
		cap &= ~HT_CAP_INFO_RX_STBC_MASK;

	neg_ht_cap->ht_capabilities_info = host_to_le16(cap);
}
static int hostap_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
			     int reason)
{
	struct hostap_driver_data *drv = priv;
	struct ieee80211_mgmt mgmt;

	if (is_broadcast_ether_addr(addr)) {
		/*
		 * New Prism2.5/3 STA firmware versions seem to have issues
		 * with this broadcast deauth frame. This gets the firmware in
		 * odd state where nothing works correctly, so let's skip
		 * sending this for the hostap driver.
		 */
		return 0;
	}

	memset(&mgmt, 0, sizeof(mgmt));
	mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
					  WLAN_FC_STYPE_DEAUTH);
	memcpy(mgmt.da, addr, ETH_ALEN);
	memcpy(mgmt.sa, own_addr, ETH_ALEN);
	memcpy(mgmt.bssid, own_addr, ETH_ALEN);
	mgmt.u.deauth.reason_code = host_to_le16(reason);
	return hostap_send_mlme(drv, (u8 *) &mgmt, IEEE80211_HDRLEN +
				sizeof(mgmt.u.deauth), 0, 0, NULL, 0);
}
static void wpa_driver_hostap_poll_client(void *priv, const u8 *own_addr,
					  const u8 *addr, int qos)
{
	struct ieee80211_hdr hdr;

	os_memset(&hdr, 0, sizeof(hdr));

	/*
	 * WLAN_FC_STYPE_NULLFUNC would be more appropriate,
	 * but it is apparently not retried so TX Exc events
	 * are not received for it.
	 * This is the reason the driver overrides the default
	 * handling.
	 */
	hdr.frame_control = IEEE80211_FC(WLAN_FC_TYPE_DATA,
					 WLAN_FC_STYPE_DATA);

	hdr.frame_control |=
		host_to_le16(WLAN_FC_FROMDS);
	os_memcpy(hdr.IEEE80211_DA_FROMDS, addr, ETH_ALEN);
	os_memcpy(hdr.IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN);
	os_memcpy(hdr.IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);

	hostap_send_mlme(priv, (u8 *)&hdr, sizeof(hdr), 0, 0, NULL, 0);
}
int hostapd_ctrl_iface_disassociate(struct hostapd_data *hapd,
                                    const char *txtaddr)
{
    u8 addr[ETH_ALEN];
    struct sta_info *sta;
    const char *pos;
    u16 reason = WLAN_REASON_PREV_AUTH_NOT_VALID;

    wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "CTRL_IFACE DISASSOCIATE %s",
            txtaddr);

    if (hwaddr_aton(txtaddr, addr))
        return -1;

    pos = os_strstr(txtaddr, " test=");
    if (pos) {
        struct ieee80211_mgmt mgmt;
        int encrypt;
        if (hapd->driver->send_frame == NULL)
            return -1;
        pos += 6;
        encrypt = atoi(pos);
        os_memset(&mgmt, 0, sizeof(mgmt));
        mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
                                          WLAN_FC_STYPE_DISASSOC);
        os_memcpy(mgmt.da, addr, ETH_ALEN);
        os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
        os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN);
        mgmt.u.disassoc.reason_code =
            host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
        if (hapd->driver->send_frame(hapd->drv_priv, (u8 *) &mgmt,
                                     IEEE80211_HDRLEN +
                                     sizeof(mgmt.u.deauth),
                                     encrypt) < 0)
            return -1;
        return 0;
    }

#ifdef CONFIG_P2P_MANAGER
    pos = os_strstr(txtaddr, " p2p=");
    if (pos) {
        return p2p_manager_disconnect(hapd, WLAN_FC_STYPE_DISASSOC,
                                      atoi(pos + 5), addr);
    }
#endif /* CONFIG_P2P_MANAGER */

    pos = os_strstr(txtaddr, " reason=");
    if (pos)
        reason = atoi(pos + 8);

    hostapd_drv_sta_disassoc(hapd, addr, reason);
    sta = ap_get_sta(hapd, addr);
    if (sta)
        ap_sta_disassociate(hapd, sta, reason);
    else if (addr[0] == 0xff)
        hostapd_free_stas(hapd);

    return 0;
}
Beispiel #19
0
static int ctrl_inject_reassocreq(struct wlantest *wt,
				  struct wlantest_bss *bss,
				  struct wlantest_sta *sta, int sender_ap,
				  enum wlantest_inject_protection prot)
{
	u8 *buf;
	struct ieee80211_mgmt *mgmt;
	int ret;

	if (prot != WLANTEST_INJECT_NORMAL &&
	    prot != WLANTEST_INJECT_UNPROTECTED)
		return -1; /* Reassociation Request frame is never protected */
	if (sta == NULL)
		return -1; /* No broadcast Reassociation Request frames */
	if (sender_ap)
		return -1; /* No Reassociation Request frame sent by AP */
	if (sta->assocreq_ies == NULL) {
		wpa_printf(MSG_INFO, "INJECT: No previous (Re)Association "
			   "Request available for " MACSTR,
			   MAC2STR(sta->addr));
		return -1;
	}

	wpa_printf(MSG_INFO, "INJECT: ReassocReq " MACSTR " -> " MACSTR,
		   MAC2STR(sta->addr), MAC2STR(bss->bssid));
	buf = os_malloc(sizeof(*mgmt) + sta->assocreq_ies_len);
	if (buf == NULL)
		return -1;
	mgmt = (struct ieee80211_mgmt *) buf;

	build_mgmt_hdr(mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_REASSOC_REQ);

	mgmt->u.reassoc_req.capab_info =
		host_to_le16(sta->assocreq_capab_info);
	mgmt->u.reassoc_req.listen_interval =
		host_to_le16(sta->assocreq_listen_int);
	os_memcpy(mgmt->u.reassoc_req.current_ap, bss->bssid, ETH_ALEN);
	os_memcpy(mgmt->u.reassoc_req.variable, sta->assocreq_ies,
		  sta->assocreq_ies_len);

	ret = wlantest_inject(wt, bss, sta, buf,
			      24 + 10 + sta->assocreq_ies_len,
			      WLANTEST_INJECT_UNPROTECTED);
	os_free(buf);
	return ret;
}
Beispiel #20
0
static int hostap_send_eapol(void *priv, const u8 *addr, const u8 *data,
                             size_t data_len, int encrypt, const u8 *own_addr)
{
    struct hostap_driver_data *drv = priv;
    struct ieee80211_hdr *hdr;
    size_t len;
    u8 *pos;
    int res;

    len = sizeof(*hdr) + sizeof(rfc1042_header) + 2 + data_len;
    hdr = os_zalloc(len);
    if (hdr == NULL) {
        printf("malloc() failed for hostapd_send_data(len=%lu)\n",
               (unsigned long) len);
        return -1;
    }

    hdr->frame_control =
        IEEE80211_FC(WLAN_FC_TYPE_DATA, WLAN_FC_STYPE_DATA);
    hdr->frame_control |= host_to_le16(WLAN_FC_FROMDS);
    /* Request TX callback */
    hdr->frame_control |= host_to_le16(BIT(1));
    if (encrypt)
        hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP);
    memcpy(hdr->IEEE80211_DA_FROMDS, addr, ETH_ALEN);
    memcpy(hdr->IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN);
    memcpy(hdr->IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);

    pos = (u8 *) (hdr + 1);
    memcpy(pos, rfc1042_header, sizeof(rfc1042_header));
    pos += sizeof(rfc1042_header);
    *((u16 *) pos) = htons(ETH_P_PAE);
    pos += 2;
    memcpy(pos, data, data_len);

    res = hostap_send_mgmt_frame(drv, (u8 *) hdr, len, 0);
    free(hdr);

    if (res < 0) {
        perror("hostapd_send_eapol: send");
        printf("hostapd_send_eapol - packet len: %lu - failed\n",
               (unsigned long) len);
    }

    return res;
}
Beispiel #21
0
u8 * hostapd_eid_ht_capabilities(struct hostapd_data *hapd, u8 *eid)
{
	struct ieee80211_ht_capabilities *cap;
	u8 *pos = eid;

	if (!hapd->iconf->ieee80211n || !hapd->iface->current_mode ||
	    hapd->conf->disable_11n)
		return eid;

	*pos++ = WLAN_EID_HT_CAP;
	*pos++ = sizeof(*cap);

	cap = (struct ieee80211_ht_capabilities *) pos;
	os_memset(cap, 0, sizeof(*cap));
	cap->ht_capabilities_info = host_to_le16(hapd->iconf->ht_capab);
	cap->a_mpdu_params = hapd->iface->current_mode->a_mpdu_params;
	os_memcpy(cap->supported_mcs_set, hapd->iface->current_mode->mcs_set,
		  16);

	/* TODO: ht_extended_capabilities (now fully disabled) */
	/* TODO: tx_bf_capability_info (now fully disabled) */
	/* TODO: asel_capabilities (now fully disabled) */

 	pos += sizeof(*cap);

	if (hapd->iconf->obss_interval) {
		struct ieee80211_obss_scan_parameters *scan_params;

		*pos++ = WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS;
		*pos++ = sizeof(*scan_params);

		scan_params = (struct ieee80211_obss_scan_parameters *) pos;
		os_memset(scan_params, 0, sizeof(*scan_params));
		scan_params->width_trigger_scan_interval =
			host_to_le16(hapd->iconf->obss_interval);

		/* Fill in default values for remaining parameters
		 * (IEEE Std 802.11-2012, 8.4.2.61 and MIB defval) */
		scan_params->scan_passive_dwell =
			host_to_le16(20);
		scan_params->scan_active_dwell =
			host_to_le16(10);
		scan_params->scan_passive_total_per_channel =
			host_to_le16(200);
		scan_params->scan_active_total_per_channel =
			host_to_le16(20);
		scan_params->channel_transition_delay_factor =
			host_to_le16(5);
		scan_params->scan_activity_threshold =
			host_to_le16(25);

		pos += sizeof(*scan_params);
	}

	return pos;
}
CWBool CW80211AssembleIEDuration(char * frame, int * offset, int value) {
	
	short int val = htons(host_to_le16(value));
	
	CW_COPY_MEMORY(frame, &(val), LEN_IE_DURATION);
	(*offset) += LEN_IE_DURATION;
	
	return CW_TRUE;
}
CWBool CW80211AssembleIESequenceNumber(char * frame, int * offset, int value) {
	
	short int val = htons(host_to_le16(value));
	
	CW_COPY_MEMORY(frame, &(val), LEN_IE_SEQ_CTRL);
	(*offset) += LEN_IE_SEQ_CTRL;
	
	return CW_TRUE;
}
CWBool CW80211AssembleIEBeaconInterval(char * frame, int * offset, short int value) {
	
	short int val = htons(host_to_le16(value));
	
	CW_COPY_MEMORY(frame, &(val), LEN_IE_BEACON_INT);
	(*offset) += LEN_IE_BEACON_INT;
	
	return CW_TRUE;
}
Beispiel #25
0
static void ieee802_11_sta_associate(void *eloop_ctx, void *timeout_ctx)
{
	hostapd *hapd = eloop_ctx;
	u8 buf[256];
	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) buf;
	u8 *p;

	if (hapd->assoc_ap_state == AUTHENTICATE)
		hapd->assoc_ap_state = ASSOCIATE;
	if (hapd->assoc_ap_state != ASSOCIATE)
		return;

	printf("Associate with AP " MACSTR " SSID=",
	       MAC2STR(hapd->conf->assoc_ap_addr));
	ieee802_11_print_ssid(hapd->assoc_ap_ssid, hapd->assoc_ap_ssid_len);
	printf(" (as station)\n");

	memset(mgmt, 0, sizeof(*mgmt));
	mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
					  WLAN_FC_STYPE_ASSOC_REQ);
	/* Request TX callback */
	mgmt->frame_control |= host_to_le16(BIT(1));
	memcpy(mgmt->da, hapd->conf->assoc_ap_addr, ETH_ALEN);
	memcpy(mgmt->sa, hapd->own_addr, ETH_ALEN);
	memcpy(mgmt->bssid, hapd->conf->assoc_ap_addr, ETH_ALEN);
	mgmt->u.assoc_req.capab_info = host_to_le16(0);
	mgmt->u.assoc_req.listen_interval = host_to_le16(1);
	p = &mgmt->u.assoc_req.variable[0];

	*p++ = WLAN_EID_SSID;
	*p++ = hapd->assoc_ap_ssid_len;
	memcpy(p, hapd->assoc_ap_ssid, hapd->assoc_ap_ssid_len);
	p += hapd->assoc_ap_ssid_len;

	p = hostapd_eid_supp_rates(hapd, p);

	if (hapd->driver.send_mgmt_frame &&
	    hapd->driver.send_mgmt_frame(hapd->driver.send_mgmt_frame,
					 mgmt, p - (u8 *) mgmt, 0) < 0)
		perror("ieee802_11_sta_associate: send");

	/* Try to authenticate again, if this attempt fails or times out. */
	eloop_register_timeout(5, 0, ieee802_11_sta_associate, hapd, NULL);
}
Beispiel #26
0
static void send_auth_reply(hostapd *hapd, struct ieee80211_mgmt *mgmt,
			    u16 auth_alg, u16 auth_transaction, u16 resp,
			    u8 *challenge)
{
	u8 buf[IEEE80211_HDRLEN + sizeof(mgmt->u.auth) + 2 +
	       WLAN_AUTH_CHALLENGE_LEN];
	struct ieee80211_mgmt *reply;
	size_t rlen;

	memset(buf, 0, sizeof(buf));
	reply = (struct ieee80211_mgmt *) buf;
	reply->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
					   WLAN_FC_STYPE_AUTH);
	/* Request TX callback */
	reply->frame_control |= host_to_le16(BIT(1));
	memcpy(reply->da, mgmt->sa, ETH_ALEN);
	memcpy(reply->sa, hapd->own_addr, ETH_ALEN);
	memcpy(reply->bssid, mgmt->bssid, ETH_ALEN);

	reply->u.auth.auth_alg = host_to_le16(auth_alg);
	reply->u.auth.auth_transaction = host_to_le16(auth_transaction);
	reply->u.auth.status_code = host_to_le16(resp);
	rlen = IEEE80211_HDRLEN + sizeof(reply->u.auth);
	if (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 2 &&
	    challenge) {
		u8 *p = reply->u.auth.variable;
		*p++ = WLAN_EID_CHALLENGE;
		*p++ = WLAN_AUTH_CHALLENGE_LEN;
		memcpy(p, challenge, WLAN_AUTH_CHALLENGE_LEN);
		rlen += 2 + WLAN_AUTH_CHALLENGE_LEN;
	} else
		challenge = NULL;

	HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
		      "authentication reply: STA=" MACSTR " auth_alg=%d "
		      "auth_transaction=%d resp=%d%s\n",
		      MAC2STR(mgmt->sa), auth_alg, auth_transaction,
		      resp, challenge ? " challenge" : "");
	if (hapd->driver.send_mgmt_frame &&
	    hapd->driver.send_mgmt_frame(hapd->driver.data, reply,
					 rlen, 0) < 0)
		perror("send_auth_reply: send");
}
void set_disable_ht40(struct ieee80211_ht_capabilities *htcaps,
		      int disabled)
{
	/* Masking these out disables HT40 */
	le16 msk = host_to_le16(HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET |
				HT_CAP_INFO_SHORT_GI40MHZ);

	if (disabled)
		htcaps->ht_capabilities_info &= ~msk;
	else
		htcaps->ht_capabilities_info |= msk;
}
Beispiel #28
0
static int hostap_send_mlme(void *priv, const u8 *msg, size_t len)
{
	struct hostap_driver_data *drv = priv;
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) msg;
	int res;

	/* Request TX callback */
	hdr->frame_control |= host_to_le16(BIT(1));
	res = send(drv->sock, msg, len, 0);
	hdr->frame_control &= ~host_to_le16(BIT(1));

	return res;
}
static int ieee802_11_send_bss_trans_mgmt_request(struct hostapd_data *hapd,
						  const u8 *addr,
						  u8 dialog_token,
						  const char *url)
{
	struct ieee80211_mgmt *mgmt;
	size_t url_len, len;
	u8 *pos;
	int res;

	if (url)
		url_len = os_strlen(url);
	else
		url_len = 0;

	mgmt = os_zalloc(sizeof(*mgmt) + (url_len ? 1 + url_len : 0));
	if (mgmt == NULL)
		return -1;
	os_memcpy(mgmt->da, addr, ETH_ALEN);
	os_memcpy(mgmt->sa, hapd->own_addr, ETH_ALEN);
	os_memcpy(mgmt->bssid, hapd->own_addr, ETH_ALEN);
	mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
					   WLAN_FC_STYPE_ACTION);
	mgmt->u.action.category = WLAN_ACTION_WNM;
	mgmt->u.action.u.bss_tm_req.action = WNM_BSS_TRANS_MGMT_REQ;
	mgmt->u.action.u.bss_tm_req.dialog_token = dialog_token;
	mgmt->u.action.u.bss_tm_req.req_mode = 0;
	mgmt->u.action.u.bss_tm_req.disassoc_timer = host_to_le16(0);
	mgmt->u.action.u.bss_tm_req.validity_interval = 1;
	pos = mgmt->u.action.u.bss_tm_req.variable;
	if (url) {
		*pos++ += url_len;
		os_memcpy(pos, url, url_len);
		pos += url_len;
	}

	wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request to "
		   MACSTR " dialog_token=%u req_mode=0x%x disassoc_timer=%u "
		   "validity_interval=%u",
		   MAC2STR(addr), dialog_token,
		   mgmt->u.action.u.bss_tm_req.req_mode,
		   le_to_host16(mgmt->u.action.u.bss_tm_req.disassoc_timer),
		   mgmt->u.action.u.bss_tm_req.validity_interval);

	len = pos - &mgmt->u.action.category;
	res = hostapd_drv_send_action(hapd, hapd->iface->freq, 0,
				      mgmt->da, &mgmt->u.action.category, len);
	os_free(mgmt);
	return res;
}
Beispiel #30
0
static void send_auth_reply(struct hostapd_data *hapd,
			    const u8 *dst, const u8 *bssid,
			    u16 auth_alg, u16 auth_transaction, u16 resp,
			    const u8 *ies, size_t ies_len)
{
	struct ieee80211_mgmt *reply;
	u8 *buf;
	size_t rlen;

	rlen = IEEE80211_HDRLEN + sizeof(reply->u.auth) + ies_len;
	buf = os_zalloc(rlen);
	if (buf == NULL)
		return;

	reply = (struct ieee80211_mgmt *) buf;
	reply->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
					    WLAN_FC_STYPE_AUTH);
	os_memcpy(reply->da, dst, ETH_ALEN);
	os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN);
	os_memcpy(reply->bssid, bssid, ETH_ALEN);

	reply->u.auth.auth_alg = host_to_le16(auth_alg);
	reply->u.auth.auth_transaction = host_to_le16(auth_transaction);
	reply->u.auth.status_code = host_to_le16(resp);

	if (ies && ies_len)
		os_memcpy(reply->u.auth.variable, ies, ies_len);

	wpa_printf(MSG_DEBUG, "authentication reply: STA=" MACSTR
		   " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu)",
		   MAC2STR(dst), auth_alg, auth_transaction,
		   resp, (unsigned long) ies_len);
	if (hapd->drv.send_mgmt_frame(hapd, reply, rlen) < 0)
		perror("send_auth_reply: send");

	os_free(buf);
}