/* only update beacons if started */ void ieee802_11_update_beacons(struct hostapd_iface *iface) { size_t i; for (i = 0; i < iface->num_bss; i++) if (iface->bss[i]->beacon_set_done) ieee802_11_set_beacon(iface->bss[i]); }
static int hostapd_wps_set_ie_cb(void *ctx, struct wpabuf *beacon_ie, struct wpabuf *probe_resp_ie) { struct hostapd_data *hapd = ctx; wpabuf_free(hapd->wps_beacon_ie); hapd->wps_beacon_ie = beacon_ie; wpabuf_free(hapd->wps_probe_resp_ie); hapd->wps_probe_resp_ie = probe_resp_ie; ieee802_11_set_beacon(hapd); return hostapd_set_ap_wps_ie(hapd); }
/* only update beacons if started */ int ieee802_11_update_beacons(struct hostapd_iface *iface) { size_t i; int ret = 0; for (i = 0; i < iface->num_bss; i++) { if (iface->bss[i]->beacon_set_done && iface->bss[i]->started && ieee802_11_set_beacon(iface->bss[i]) < 0) ret = -1; } return ret; }
static void hostapd_reload_bss(struct hostapd_data *hapd) { #ifndef CONFIG_NO_RADIUS radius_client_reconfig(hapd->radius, hapd->conf->radius); #endif /* CONFIG_NO_RADIUS */ if (hostapd_setup_wpa_psk(hapd->conf)) { wpa_printf(MSG_ERROR, "Failed to re-configure WPA PSK " "after reloading configuration"); } if (hapd->conf->ieee802_1x || hapd->conf->wpa) hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 1); else hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 0); if (hapd->conf->wpa && hapd->wpa_auth == NULL) { hostapd_setup_wpa(hapd); if (hapd->wpa_auth) wpa_init_keys(hapd->wpa_auth); } else if (hapd->conf->wpa) { const u8 *wpa_ie; size_t wpa_ie_len; hostapd_reconfig_wpa(hapd); wpa_ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &wpa_ie_len); if (hostapd_set_generic_elem(hapd, wpa_ie, wpa_ie_len)) wpa_printf(MSG_ERROR, "Failed to configure WPA IE for " "the kernel driver."); } else if (hapd->wpa_auth) { wpa_deinit(hapd->wpa_auth); hapd->wpa_auth = NULL; hostapd_set_privacy(hapd, 0); hostapd_setup_encryption(hapd->conf->iface, hapd); hostapd_set_generic_elem(hapd, (u8 *) "", 0); } ieee802_11_set_beacon(hapd); hostapd_update_wps(hapd); if (hapd->conf->ssid.ssid_set && hostapd_set_ssid(hapd, (u8 *) hapd->conf->ssid.ssid, hapd->conf->ssid.ssid_len)) { wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver"); /* try to continue */ } wpa_printf(MSG_DEBUG, "Reconfigured interface %s", hapd->conf->iface); }
void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht, int offset) { #ifdef NEED_AP_MLME int channel; hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "driver had channel switch: " "freq=%d, ht=%d, offset=%d", freq, ht, offset); channel = hostapd_hw_get_channel(hapd, freq); if (!channel) { hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_WARNING, "driver switched to " "bad channel!"); return; } hapd->iconf->channel = channel; hapd->iconf->ieee80211n = ht; hapd->iconf->secondary_channel = offset; if (hapd->iface->freq == freq) return; hapd->iface->freq = freq; if (hostapd_set_freq(hapd, hapd->iconf->hw_mode, freq, hapd->iconf->channel, hapd->iconf->ieee80211n, hapd->iconf->secondary_channel)) { hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_WARNING, "failed to update the freq !"); return; } hapd->next_channel = NULL; /* update the DS IE */ ieee802_11_set_beacon(hapd); wpa_printf(MSG_DEBUG, "AP/GO moved to channel %d", channel); #endif /* NEED_AP_MLME */ }
static void update_channel_utilization(void *eloop_data, void *user_data) { struct hostapd_data *hapd = eloop_data; unsigned int sec, usec; int err; if (!(hapd->beacon_set_done && hapd->started)) return; err = hostapd_drv_get_survey(hapd, hapd->iface->freq); if (err) { wpa_printf(MSG_ERROR, "BSS Load: Failed to get survey data"); return; } ieee802_11_set_beacon(hapd); sec = ((hapd->bss_load_update_timeout / 1000) * 1024) / 1000; usec = (hapd->bss_load_update_timeout % 1000) * 1024; eloop_register_timeout(sec, usec, update_channel_utilization, hapd, NULL); }
static void update_channel_utilization(void *eloop_data, void *user_data) { struct hostapd_data *hapd = eloop_data; unsigned int sec, usec; int err; struct hostapd_iface *iface = hapd->iface; if (!(hapd->beacon_set_done && hapd->started)) return; err = hostapd_drv_get_survey(hapd, hapd->iface->freq); if (err) { wpa_printf(MSG_ERROR, "BSS Load: Failed to get survey data"); return; } ieee802_11_set_beacon(hapd); if (get_bss_load_update_timeout(hapd, &sec, &usec) < 0) return; if (hapd->conf->chan_util_avg_period) { iface->chan_util_samples_sum += iface->channel_utilization; iface->chan_util_num_sample_periods += hapd->conf->bss_load_update_period; if (iface->chan_util_num_sample_periods >= hapd->conf->chan_util_avg_period) { iface->chan_util_average = iface->chan_util_samples_sum / (iface->chan_util_num_sample_periods / hapd->conf->bss_load_update_period); iface->chan_util_samples_sum = 0; iface->chan_util_num_sample_periods = 0; } } eloop_register_timeout(sec, usec, update_channel_utilization, hapd, NULL); }
void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht, int offset, int width, int cf1, int cf2) { #ifdef NEED_AP_MLME int channel, chwidth, seg0_idx = 0, seg1_idx = 0; hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "driver had channel switch: " "freq=%d, ht=%d, offset=%d, width=%d, cf1=%d, cf2=%d", freq, ht, offset, width, cf1, cf2); hapd->iface->freq = freq; channel = hostapd_hw_get_channel(hapd, freq); if (!channel) { hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_WARNING, "driver switched to " "bad channel!"); return; } switch (width) { case CHAN_WIDTH_80: chwidth = VHT_CHANWIDTH_80MHZ; break; case CHAN_WIDTH_80P80: chwidth = VHT_CHANWIDTH_80P80MHZ; break; case CHAN_WIDTH_160: chwidth = VHT_CHANWIDTH_160MHZ; break; case CHAN_WIDTH_20_NOHT: case CHAN_WIDTH_20: case CHAN_WIDTH_40: default: chwidth = VHT_CHANWIDTH_USE_HT; break; } switch (hapd->iface->current_mode->mode) { case HOSTAPD_MODE_IEEE80211A: if (cf1 > 5000) seg0_idx = (cf1 - 5000) / 5; if (cf2 > 5000) seg1_idx = (cf2 - 5000) / 5; break; default: seg0_idx = hostapd_hw_get_channel(hapd, cf1); seg1_idx = hostapd_hw_get_channel(hapd, cf2); break; } hapd->iconf->channel = channel; hapd->iconf->ieee80211n = ht; hapd->iconf->secondary_channel = offset; hapd->iconf->vht_oper_chwidth = chwidth; hapd->iconf->vht_oper_centr_freq_seg0_idx = seg0_idx; hapd->iconf->vht_oper_centr_freq_seg1_idx = seg1_idx; if (hapd->csa_in_progress && freq == hapd->cs_freq_params.freq) { hostapd_cleanup_cs_params(hapd); ieee802_11_set_beacon(hapd); wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED "freq=%d", freq); } #endif /* NEED_AP_MLME */ }
void wpa_supplicant_event(void *ctx, enum wpa_event_type event, union wpa_event_data *data) { struct hostapd_data *hapd = ctx; #ifndef CONFIG_NO_STDOUT_DEBUG int level = MSG_DEBUG; if (event == EVENT_RX_MGMT && data->rx_mgmt.frame && data->rx_mgmt.frame_len >= 24) { const struct ieee80211_hdr *hdr; u16 fc; hdr = (const struct ieee80211_hdr *) data->rx_mgmt.frame; fc = le_to_host16(hdr->frame_control); if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT && WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON) level = MSG_EXCESSIVE; if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT && WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_REQ) level = MSG_EXCESSIVE; } wpa_dbg(hapd->msg_ctx, level, "Event %s (%d) received", event_to_string(event), event); #endif /* CONFIG_NO_STDOUT_DEBUG */ switch (event) { case EVENT_MICHAEL_MIC_FAILURE: michael_mic_failure(hapd, data->michael_mic_failure.src, 1); break; case EVENT_SCAN_RESULTS: if (hapd->iface->scan_cb) hapd->iface->scan_cb(hapd->iface); break; case EVENT_WPS_BUTTON_PUSHED: hostapd_wps_button_pushed(hapd, NULL); break; #ifdef NEED_AP_MLME case EVENT_TX_STATUS: switch (data->tx_status.type) { case WLAN_FC_TYPE_MGMT: hostapd_mgmt_tx_cb(hapd, data->tx_status.data, data->tx_status.data_len, data->tx_status.stype, data->tx_status.ack); break; case WLAN_FC_TYPE_DATA: hostapd_tx_status(hapd, data->tx_status.dst, data->tx_status.data, data->tx_status.data_len, data->tx_status.ack); break; } break; case EVENT_EAPOL_TX_STATUS: hostapd_eapol_tx_status(hapd, data->eapol_tx_status.dst, data->eapol_tx_status.data, data->eapol_tx_status.data_len, data->eapol_tx_status.ack); break; case EVENT_DRIVER_CLIENT_POLL_OK: hostapd_client_poll_ok(hapd, data->client_poll.addr); break; case EVENT_RX_FROM_UNKNOWN: hostapd_rx_from_unknown_sta(hapd, data->rx_from_unknown.bssid, data->rx_from_unknown.addr, data->rx_from_unknown.wds); break; #endif /* NEED_AP_MLME */ case EVENT_RX_MGMT: if (!data->rx_mgmt.frame) break; #ifdef NEED_AP_MLME if (hostapd_mgmt_rx(hapd, &data->rx_mgmt) > 0) break; #endif /* NEED_AP_MLME */ hostapd_action_rx(hapd, &data->rx_mgmt); break; case EVENT_RX_PROBE_REQ: if (data->rx_probe_req.sa == NULL || data->rx_probe_req.ie == NULL) break; hostapd_probe_req_rx(hapd, data->rx_probe_req.sa, data->rx_probe_req.da, data->rx_probe_req.bssid, data->rx_probe_req.ie, data->rx_probe_req.ie_len, data->rx_probe_req.ssi_signal); break; case EVENT_NEW_STA: hostapd_event_new_sta(hapd, data->new_sta.addr); break; case EVENT_EAPOL_RX: hostapd_event_eapol_rx(hapd, data->eapol_rx.src, data->eapol_rx.data, data->eapol_rx.data_len); break; case EVENT_ASSOC: if (!data) return; hostapd_notif_assoc(hapd, data->assoc_info.addr, data->assoc_info.req_ies, data->assoc_info.req_ies_len, data->assoc_info.reassoc); break; case EVENT_DISASSOC: if (data) hostapd_notif_disassoc(hapd, data->disassoc_info.addr); break; case EVENT_DEAUTH: if (data) hostapd_notif_disassoc(hapd, data->deauth_info.addr); break; case EVENT_STATION_LOW_ACK: if (!data) break; hostapd_event_sta_low_ack(hapd, data->low_ack.addr); break; case EVENT_AUTH: hostapd_notif_auth(hapd, &data->auth); break; case EVENT_CH_SWITCH: if (!data) break; hostapd_event_ch_switch(hapd, data->ch_switch.freq, data->ch_switch.ht_enabled, data->ch_switch.ch_offset, data->ch_switch.ch_width, data->ch_switch.cf1, data->ch_switch.cf2); break; case EVENT_CONNECT_FAILED_REASON: if (!data) break; hostapd_event_connect_failed_reason( hapd, data->connect_failed_reason.addr, data->connect_failed_reason.code); break; case EVENT_SURVEY: hostapd_event_get_survey(hapd->iface, &data->survey_results); break; #ifdef NEED_AP_MLME case EVENT_INTERFACE_UNAVAILABLE: hostapd_event_iface_unavailable(hapd); break; case EVENT_DFS_RADAR_DETECTED: if (!data) break; hostapd_event_dfs_radar_detected(hapd, &data->dfs_event); break; case EVENT_DFS_CAC_FINISHED: if (!data) break; hostapd_event_dfs_cac_finished(hapd, &data->dfs_event); break; case EVENT_DFS_CAC_ABORTED: if (!data) break; hostapd_event_dfs_cac_aborted(hapd, &data->dfs_event); break; case EVENT_DFS_NOP_FINISHED: if (!data) break; hostapd_event_dfs_nop_finished(hapd, &data->dfs_event); break; case EVENT_CHANNEL_LIST_CHANGED: /* channel list changed (regulatory?), update channel list */ /* TODO: check this. hostapd_get_hw_features() initializes * too much stuff. */ /* hostapd_get_hw_features(hapd->iface); */ hostapd_channel_list_updated( hapd->iface, data->channel_list_changed.initiator); break; case EVENT_DFS_CAC_STARTED: if (!data) break; hostapd_event_dfs_cac_started(hapd, &data->dfs_event); break; #endif /* NEED_AP_MLME */ case EVENT_INTERFACE_ENABLED: wpa_msg(hapd->msg_ctx, MSG_INFO, INTERFACE_ENABLED); if (hapd->disabled && hapd->started) { hapd->disabled = 0; /* * Try to re-enable interface if the driver stopped it * when the interface got disabled. */ wpa_auth_reconfig_group_keys(hapd->wpa_auth); hapd->reenable_beacon = 1; ieee802_11_set_beacon(hapd); } break; case EVENT_INTERFACE_DISABLED: hostapd_free_stas(hapd); wpa_msg(hapd->msg_ctx, MSG_INFO, INTERFACE_DISABLED); hapd->disabled = 1; break; #ifdef CONFIG_ACS case EVENT_ACS_CHANNEL_SELECTED: hostapd_acs_channel_selected(hapd, &data->acs_selected_channels); break; #endif /* CONFIG_ACS */ default: wpa_printf(MSG_DEBUG, "Unknown event %d", event); break; } }
static void hostapd_reconfig_bss(struct hostapd_data *hapd, struct hostapd_bss_config *newbss, struct hostapd_bss_config *oldbss, struct hostapd_config *oldconf, int beacon_changed) { struct hostapd_config_change change; int encr_changed = 0; struct radius_client_data *old_radius; radius_client_flush(hapd->radius, 0); if (hostapd_set_dtim_period(hapd, newbss->dtim_period)) printf("Could not set DTIM period for kernel driver\n"); if (newbss->ssid.ssid_len != oldbss->ssid.ssid_len || memcmp(newbss->ssid.ssid, oldbss->ssid.ssid, newbss->ssid.ssid_len) != 0) { if (hostapd_set_ssid(hapd, (u8 *) newbss->ssid.ssid, newbss->ssid.ssid_len)) printf("Could not set SSID for kernel driver\n"); beacon_changed++; } if (newbss->ignore_broadcast_ssid != oldbss->ignore_broadcast_ssid) beacon_changed++; if (hostapd_wep_key_cmp(&newbss->ssid.wep, &oldbss->ssid.wep)) { encr_changed++; beacon_changed++; } vlan_reconfig(hapd, oldconf, oldbss); if (beacon_changed) { HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "Updating beacon frame " "information\n"); ieee802_11_set_beacon(hapd); } change.hapd = hapd; change.oldconf = oldconf; change.newconf = hapd->iconf; change.oldbss = oldbss; change.newbss = newbss; change.mac_acl_changed = hostapd_acl_diff(newbss, oldbss); if (newbss->max_num_sta != oldbss->max_num_sta && newbss->max_num_sta < hapd->num_sta) { change.num_sta_remove = hapd->num_sta - newbss->max_num_sta; } else change.num_sta_remove = 0; ap_for_each_sta(hapd, hostapd_config_reload_sta, &change); old_radius = hapd->radius; hapd->radius = radius_client_reconfig(hapd->radius, hapd, oldbss->radius, newbss->radius); hapd->radius_client_reconfigured = old_radius != hapd->radius || hostapd_ip_diff(&newbss->own_ip_addr, &oldbss->own_ip_addr); ieee802_1x_reconfig(hapd, oldconf, oldbss); iapp_reconfig(hapd, oldconf, oldbss); hostapd_acl_reconfig(hapd, oldconf); accounting_reconfig(hapd, oldconf); }
static void asd_reconfig_bss(struct asd_data *wasd, struct asd_bss_config *newbss, struct asd_bss_config *oldbss, struct asd_config *oldconf, int beacon_changed) { struct asd_config_change change; int encr_changed = 0; struct radius_client_data *old_radius; //radius_client_flush(wasd->radius, 0); if (asd_set_dtim_period(wasd, newbss->dtim_period)) asd_printf(ASD_DEFAULT,MSG_DEBUG,"Could not set DTIM period for kernel driver\n"); if (newbss->ssid.ssid_len != oldbss->ssid.ssid_len || os_memcmp(newbss->ssid.ssid, oldbss->ssid.ssid, newbss->ssid.ssid_len) != 0) { if (asd_set_ssid(wasd, (u8 *) newbss->ssid.ssid, newbss->ssid.ssid_len)) asd_printf(ASD_DEFAULT,MSG_DEBUG,"Could not set SSID for kernel driver\n"); beacon_changed++; } if (newbss->ignore_broadcast_ssid != oldbss->ignore_broadcast_ssid) beacon_changed++; if (asd_wep_key_cmp(&newbss->ssid.wep, &oldbss->ssid.wep)) { encr_changed++; beacon_changed++; } vlan_reconfig(wasd, oldconf, oldbss); if (beacon_changed) { asd_printf(ASD_DEFAULT,MSG_DEBUG, "Updating beacon frame information"); ieee802_11_set_beacon(wasd); } change.wasd = wasd; change.oldconf = oldconf; change.newconf = wasd->iconf; change.oldbss = oldbss; change.newbss = newbss; change.mac_acl_changed = asd_acl_diff(newbss, oldbss); if (newbss->max_num_sta != oldbss->max_num_sta && newbss->max_num_sta < wasd->num_sta) { change.num_sta_remove = wasd->num_sta - newbss->max_num_sta; } else change.num_sta_remove = 0; ap_for_each_sta(wasd, asd_config_reload_sta, &change); old_radius = wasd->radius; wasd->radius = radius_client_reconfig(wasd->radius, wasd, oldbss->radius, newbss->radius); wasd->radius_client_reconfigured = old_radius != wasd->radius || asd_ip_diff(&newbss->own_ip_addr, &oldbss->own_ip_addr); ieee802_1x_reconfig(wasd, oldconf, oldbss); iapp_reconfig(wasd, oldconf, oldbss); asd_acl_reconfig(wasd, oldconf); accounting_reconfig(wasd, oldconf); }
void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht, int offset, int width, int cf1, int cf2) { /* TODO: If OCV is enabled deauth STAs that don't perform a SA Query */ #ifdef NEED_AP_MLME int channel, chwidth, is_dfs; u8 seg0_idx = 0, seg1_idx = 0; size_t i; hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "driver had channel switch: freq=%d, ht=%d, vht_ch=0x%x, offset=%d, width=%d (%s), cf1=%d, cf2=%d", freq, ht, hapd->iconf->ch_switch_vht_config, offset, width, channel_width_to_string(width), cf1, cf2); hapd->iface->freq = freq; channel = hostapd_hw_get_channel(hapd, freq); if (!channel) { hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_WARNING, "driver switched to bad channel!"); return; } switch (width) { case CHAN_WIDTH_80: chwidth = VHT_CHANWIDTH_80MHZ; break; case CHAN_WIDTH_80P80: chwidth = VHT_CHANWIDTH_80P80MHZ; break; case CHAN_WIDTH_160: chwidth = VHT_CHANWIDTH_160MHZ; break; case CHAN_WIDTH_20_NOHT: case CHAN_WIDTH_20: case CHAN_WIDTH_40: default: chwidth = VHT_CHANWIDTH_USE_HT; break; } switch (hapd->iface->current_mode->mode) { case HOSTAPD_MODE_IEEE80211A: if (cf1 > 5000) seg0_idx = (cf1 - 5000) / 5; if (cf2 > 5000) seg1_idx = (cf2 - 5000) / 5; break; default: ieee80211_freq_to_chan(cf1, &seg0_idx); ieee80211_freq_to_chan(cf2, &seg1_idx); break; } hapd->iconf->channel = channel; hapd->iconf->ieee80211n = ht; if (!ht) { hapd->iconf->ieee80211ac = 0; } else if (hapd->iconf->ch_switch_vht_config) { /* CHAN_SWITCH VHT config */ if (hapd->iconf->ch_switch_vht_config & CH_SWITCH_VHT_ENABLED) hapd->iconf->ieee80211ac = 1; else if (hapd->iconf->ch_switch_vht_config & CH_SWITCH_VHT_DISABLED) hapd->iconf->ieee80211ac = 0; } hapd->iconf->ch_switch_vht_config = 0; hapd->iconf->secondary_channel = offset; hapd->iconf->vht_oper_chwidth = chwidth; hapd->iconf->vht_oper_centr_freq_seg0_idx = seg0_idx; hapd->iconf->vht_oper_centr_freq_seg1_idx = seg1_idx; is_dfs = ieee80211_is_dfs(freq, hapd->iface->hw_features, hapd->iface->num_hw_features); if (hapd->csa_in_progress && freq == hapd->cs_freq_params.freq) { hostapd_cleanup_cs_params(hapd); ieee802_11_set_beacon(hapd); wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED "freq=%d dfs=%d", freq, is_dfs); } else if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) { wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED "freq=%d dfs=%d", freq, is_dfs); } for (i = 0; i < hapd->iface->num_bss; i++) hostapd_neighbor_set_own_report(hapd->iface->bss[i]); #endif /* NEED_AP_MLME */ }