/** * hostapd_interface_init - Read configuration file and init BSS data * * This function is used to parse configuration file for a full interface (one * or more BSSes sharing the same radio) and allocate memory for the BSS * interfaces. No actiual driver operations are started. */ static struct hostapd_iface * hostapd_interface_init(struct hapd_interfaces *interfaces, const char *config_fname, int debug) { struct hostapd_iface *iface; int k; wpa_printf(MSG_ERROR, "Configuration file: %s", config_fname); iface = hostapd_init(interfaces, config_fname); if (!iface) return NULL; iface->interfaces = interfaces; for (k = 0; k < debug; k++) { if (iface->bss[0]->conf->logger_stdout_level > 0) iface->bss[0]->conf->logger_stdout_level--; } if (iface->conf->bss[0]->iface[0] == '\0' && !hostapd_drv_none(iface->bss[0])) { wpa_printf(MSG_ERROR, "Interface name not specified in %s", config_fname); hostapd_interface_deinit_free(iface); return NULL; } return iface; }
static struct hostapd_iface * hostapd_interface_init(struct hapd_interfaces *interfaces, const char *config_fname, int debug) { struct hostapd_iface *iface; int k; wpa_printf(MSG_ERROR, "Configuration file: %s", config_fname); iface = hostapd_init(config_fname); if (!iface) return NULL; iface->interfaces = interfaces; for (k = 0; k < debug; k++) { if (iface->bss[0]->conf->logger_stdout_level > 0) iface->bss[0]->conf->logger_stdout_level--; } if (iface->conf->bss[0].iface[0] != 0 || hostapd_drv_none(iface->bss[0])) { if (hostapd_driver_init(iface) || hostapd_setup_interface(iface)) { hostapd_interface_deinit_free(iface); return NULL; } } return iface; }
int hostapd_get_hw_features(struct hostapd_iface *iface) { struct hostapd_data *hapd = iface->bss[0]; int ret = 0, i, j; u16 num_modes, flags; struct hostapd_hw_modes *modes; if (hostapd_drv_none(hapd)) return -1; modes = hostapd_get_hw_feature_data(hapd, &num_modes, &flags); if (modes == NULL) { hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "Fetching hardware channel/rate support not " "supported."); return -1; } iface->hw_flags = flags; hostapd_free_hw_features(iface->hw_features, iface->num_hw_features); iface->hw_features = modes; iface->num_hw_features = num_modes; for (i = 0; i < num_modes; i++) { struct hostapd_hw_modes *feature = &modes[i]; /* set flag for channels we can use in current regulatory * domain */ for (j = 0; j < feature->num_channels; j++) { /* * Disable all channels that are marked not to allow * IBSS operation or active scanning. In addition, * disable all channels that require radar detection, * since that (in addition to full DFS) is not yet * supported. */ if (feature->channels[j].flag & (HOSTAPD_CHAN_NO_IBSS | HOSTAPD_CHAN_PASSIVE_SCAN | HOSTAPD_CHAN_RADAR)) feature->channels[j].flag |= HOSTAPD_CHAN_DISABLED; if (feature->channels[j].flag & HOSTAPD_CHAN_DISABLED) continue; wpa_printf(MSG_MSGDUMP, "Allowed channel: mode=%d " "chan=%d freq=%d MHz max_tx_power=%d dBm", feature->mode, feature->channels[j].chan, feature->channels[j].freq, feature->channels[j].max_tx_power); } } return ret; }
int hostapd_get_hw_features(struct hostapd_iface *iface) { struct hostapd_data *hapd = iface->bss[0]; int i, j; u16 num_modes, flags; struct hostapd_hw_modes *modes; if (hostapd_drv_none(hapd)) { return -1; } modes = hostapd_get_hw_feature_data(hapd, &num_modes, &flags); if (modes == NULL) { hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "Fetching hardware channel/rate support not " "supported."); return -1; } iface->hw_flags = flags; hostapd_free_hw_features(iface->hw_features, iface->num_hw_features); iface->hw_features = modes; iface->num_hw_features = num_modes; for (i = 0; i < num_modes; i++) { struct hostapd_hw_modes *feature = &modes[i]; int dfs_enabled = hapd->iconf->ieee80211h && (iface->drv_flags & WPA_DRIVER_FLAGS_RADAR); /* set flag for channels we can use in current regulatory * domain */ for (j = 0; j < feature->num_channels; j++) { int dfs = 0; /* * Disable all channels that are marked not to allow * to initiate radiation (a.k.a. passive scan and no * IBSS). * Use radar channels only if the driver supports DFS. */ if ((feature->channels[j].flag & HOSTAPD_CHAN_RADAR) && dfs_enabled) { dfs = 1; } else if (((feature->channels[j].flag & HOSTAPD_CHAN_RADAR) && !(iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)) || (feature->channels[j].flag & HOSTAPD_CHAN_NO_IR)) { feature->channels[j].flag |= HOSTAPD_CHAN_DISABLED; } if (feature->channels[j].flag & HOSTAPD_CHAN_DISABLED) { continue; } wpa_printf(MSG_MSGDUMP, "Allowed channel: mode=%d " "chan=%d freq=%d MHz max_tx_power=%d dBm%s", feature->mode, feature->channels[j].chan, feature->channels[j].freq, feature->channels[j].max_tx_power, dfs ? dfs_info(&feature->channels[j]) : ""); } } return 0; }
/** * hostapd_validate_bssid_configuration - Validate BSSID configuration * @iface: Pointer to interface data * Returns: 0 on success, -1 on failure * * This function is used to validate that the configured BSSIDs are valid. */ static int hostapd_validate_bssid_configuration(struct hostapd_iface *iface) { u8 mask[ETH_ALEN] = { 0 }; struct hostapd_data *hapd = iface->bss[0]; unsigned int i = iface->conf->num_bss, bits = 0, j; int auto_addr = 0; if (hostapd_drv_none(hapd)) return 0; /* Generate BSSID mask that is large enough to cover the BSSIDs. */ /* Make sure that additional BSSIDs fit for pwifi. */ if (i < PWIFI_MAX_BSS_COUNT) { i = PWIFI_MAX_BSS_COUNT; } /* Determine the bits necessary to cover the number of BSSIDs. */ for (i--; i; i >>= 1) bits++; /* Determine the bits necessary to any configured BSSIDs, if they are higher than the number of BSSIDs. */ for (j = 0; j < iface->conf->num_bss; j++) { if (hostapd_mac_comp_empty(iface->conf->bss[j].bssid) == 0) { if (j) auto_addr++; continue; } for (i = 0; i < ETH_ALEN; i++) { mask[i] |= iface->conf->bss[j].bssid[i] ^ hapd->own_addr[i]; } } if (!auto_addr) goto skip_mask_ext; for (i = 0; i < ETH_ALEN && mask[i] == 0; i++) ; j = 0; if (i < ETH_ALEN) { j = (5 - i) * 8; while (mask[i] != 0) { mask[i] >>= 1; j++; } }
static int hostapd_flush_old_stations(struct hostapd_data *hapd) { int ret = 0; u8 addr[ETH_ALEN]; if (hostapd_drv_none(hapd) || hapd->drv_priv == NULL) return 0; wpa_printf(MSG_DEBUG, "Flushing old station entries"); if (hostapd_flush(hapd)) { wpa_printf(MSG_WARNING, "Could not connect to kernel driver."); ret = -1; } wpa_printf(MSG_DEBUG, "Deauthenticate all stations"); os_memset(addr, 0xff, ETH_ALEN); hostapd_drv_sta_deauth(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID); hostapd_free_stas(hapd); return ret; }
static int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason) { int ret = 0; u8 addr[ETH_ALEN]; if (hostapd_drv_none(hapd) || hapd->drv_priv == NULL) return 0; wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "Flushing old station entries"); if (hostapd_flush(hapd)) { wpa_msg(hapd->msg_ctx, MSG_WARNING, "Could not connect to " "kernel driver"); ret = -1; } wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "Deauthenticate all stations"); os_memset(addr, 0xff, ETH_ALEN); hostapd_drv_sta_deauth(hapd, addr, reason); hostapd_free_stas(hapd); return ret; }
int hostapd_setup_wpa(struct hostapd_data *hapd) { struct wpa_auth_config _conf; struct wpa_auth_callbacks cb; const u8 *wpa_ie; size_t wpa_ie_len; hostapd_wpa_auth_conf(hapd->conf, &_conf); if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_EAPOL_TX_STATUS) _conf.tx_status = 1; os_memset(&cb, 0, sizeof(cb)); cb.ctx = hapd; cb.logger = hostapd_wpa_auth_logger; cb.disconnect = hostapd_wpa_auth_disconnect; cb.mic_failure_report = hostapd_wpa_auth_mic_failure_report; cb.set_eapol = hostapd_wpa_auth_set_eapol; cb.get_eapol = hostapd_wpa_auth_get_eapol; cb.get_psk = hostapd_wpa_auth_get_psk; cb.get_msk = hostapd_wpa_auth_get_msk; cb.set_key = hostapd_wpa_auth_set_key; cb.get_seqnum = hostapd_wpa_auth_get_seqnum; cb.send_eapol = hostapd_wpa_auth_send_eapol; cb.for_each_sta = hostapd_wpa_auth_for_each_sta; cb.for_each_auth = hostapd_wpa_auth_for_each_auth; cb.send_ether = hostapd_wpa_auth_send_ether; #ifdef CONFIG_IEEE80211R cb.send_ft_action = hostapd_wpa_auth_send_ft_action; cb.add_sta = hostapd_wpa_auth_add_sta; #endif /* CONFIG_IEEE80211R */ hapd->wpa_auth = wpa_init(hapd->own_addr, &_conf, &cb); if (hapd->wpa_auth == NULL) { wpa_printf(MSG_ERROR, "WPA initialization failed."); return -1; } if (hostapd_set_privacy(hapd, 1)) { wpa_printf(MSG_ERROR, "Could not set PrivacyInvoked " "for interface %s", hapd->conf->iface); return -1; } 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."); return -1; } if (rsn_preauth_iface_init(hapd)) { wpa_printf(MSG_ERROR, "Initialization of RSN " "pre-authentication failed."); return -1; } #ifdef CONFIG_IEEE80211R if (!hostapd_drv_none(hapd)) { hapd->l2 = l2_packet_init(hapd->conf->bridge[0] ? hapd->conf->bridge : hapd->conf->iface, NULL, ETH_P_RRB, hostapd_rrb_receive, hapd, 1); if (hapd->l2 == NULL && (hapd->driver == NULL || hapd->driver->send_ether == NULL)) { wpa_printf(MSG_ERROR, "Failed to open l2_packet " "interface"); return -1; } } #endif /* CONFIG_IEEE80211R */ return 0; }
static int hostapd_setup_bss_dynamically(struct hostapd_data *hapd) { struct hostapd_bss_config *conf = hapd->conf; if (conf->wmm_enabled < 0) conf->wmm_enabled = hapd->iconf->ieee80211n; if (hostapd_setup_wpa_psk(conf)) { wpa_printf(MSG_ERROR, "WPA-PSK setup failed."); return -1; } if (wpa_debug_level == MSG_MSGDUMP) conf->radius->msg_dumps = 1; #ifndef CONFIG_NO_RADIUS hapd->radius = radius_client_init(hapd, conf->radius); if (hapd->radius == NULL) { wpa_printf(MSG_ERROR, "RADIUS client initialization failed."); return -1; } if (hapd->conf->radius_das_port) { struct radius_das_conf das_conf; os_memset(&das_conf, 0, sizeof(das_conf)); das_conf.port = hapd->conf->radius_das_port; das_conf.shared_secret = hapd->conf->radius_das_shared_secret; das_conf.shared_secret_len = hapd->conf->radius_das_shared_secret_len; das_conf.client_addr = &hapd->conf->radius_das_client_addr; das_conf.time_window = hapd->conf->radius_das_time_window; das_conf.require_event_timestamp = hapd->conf->radius_das_require_event_timestamp; das_conf.ctx = hapd; das_conf.disconnect = hostapd_das_disconnect; hapd->radius_das = radius_das_init(&das_conf); if (hapd->radius_das == NULL) { wpa_printf(MSG_ERROR, "RADIUS DAS initialization " "failed."); return -1; } } #endif /* CONFIG_NO_RADIUS */ if (hostapd_acl_init(hapd)) { wpa_printf(MSG_ERROR, "ACL initialization failed."); return -1; } if (hostapd_init_wps(hapd, conf)) return -1; if (authsrv_init(hapd) < 0) return -1; if (ieee802_1x_init(hapd)) { wpa_printf(MSG_ERROR, "IEEE 802.1X initialization failed."); return -1; } if (hapd->conf->wpa && hostapd_setup_wpa(hapd)) return -1; if (accounting_init(hapd)) { wpa_printf(MSG_ERROR, "Accounting initialization failed."); return -1; } if (hapd->conf->ieee802_11f && (hapd->iapp = iapp_init(hapd, hapd->conf->iapp_iface)) == NULL) { wpa_printf(MSG_ERROR, "IEEE 802.11F (IAPP) initialization " "failed."); return -1; } #ifdef CONFIG_INTERWORKING if (gas_serv_init(hapd)) { wpa_printf(MSG_ERROR, "GAS server initialization failed"); return -1; } #endif /* CONFIG_INTERWORKING */ if (hapd->iface->interfaces && hapd->iface->interfaces->ctrl_iface_init && hapd->iface->interfaces->ctrl_iface_init(hapd)) { wpa_printf(MSG_ERROR, "Failed to setup control interface"); return -1; } if (!hostapd_drv_none(hapd) && vlan_init(hapd)) { wpa_printf(MSG_ERROR, "VLAN initialization failed."); return -1; } if (hapd->wpa_auth && wpa_init_keys(hapd->wpa_auth) < 0) return -1; if (hapd->driver && hapd->driver->set_operstate) hapd->driver->set_operstate(hapd->drv_priv, 1); return 0; }