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; }
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); }
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)); }
/* 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; }
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; }
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; }
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; }
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; }
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; }
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); }
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; }
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; }
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; }
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; }
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); }
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; }
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; }
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); }