hostapd.c
来自「最新的Host AP 新添加了许多pcmcia 的驱动」· C语言 代码 · 共 2,028 行 · 第 1/4 页
C
2,028 行
return -1; m = os_zalloc(sizeof(*m) + data_len); if (m == NULL) return -1; mlen = ((u8 *) &m->u - (u8 *) m) + data_len; m->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_ACTION); os_memcpy(m->da, dst, ETH_ALEN); os_memcpy(m->sa, hapd->own_addr, ETH_ALEN); os_memcpy(m->bssid, hapd->own_addr, ETH_ALEN); os_memcpy(&m->u, data, data_len); res = hostapd_send_mgmt_frame(hapd, (u8 *) m, mlen, 0); os_free(m); return res;}static struct wpa_state_machine *hostapd_wpa_auth_add_sta(void *ctx, const u8 *sta_addr){ struct hostapd_data *hapd = ctx; struct sta_info *sta; sta = ap_sta_add(hapd, sta_addr); if (sta == NULL) return NULL; if (sta->wpa_sm) return sta->wpa_sm; sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, sta->addr); if (sta->wpa_sm == NULL) { ap_free_sta(hapd, sta); return NULL; } sta->auth_alg = WLAN_AUTH_FT; return sta->wpa_sm;}static void hostapd_rrb_receive(void *ctx, const u8 *src_addr, const u8 *buf, size_t len){ struct hostapd_data *hapd = ctx; wpa_ft_rrb_rx(hapd->wpa_auth, src_addr, buf, len);}#endif /* CONFIG_IEEE80211R *//** * 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 res; if (hostapd_drv_none(hapd)) return 0; /* Generate BSSID mask that is large enough to cover the BSSIDs. */ /* 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) continue; for (i = 0; i < ETH_ALEN; i++) { mask[i] |= iface->conf->bss[j].bssid[i] ^ hapd->own_addr[i]; } } 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++; } } if (bits < j) bits = j; if (bits > 40) return -1; os_memset(mask, 0xff, ETH_ALEN); j = bits / 8; for (i = 5; i > 5 - j; i--) mask[i] = 0; j = bits % 8; while (j--) mask[i] <<= 1; wpa_printf(MSG_DEBUG, "BSS count %lu, BSSID mask " MACSTR " (%d bits)", (unsigned long) iface->conf->num_bss, MAC2STR(mask), bits); res = hostapd_valid_bss_mask(hapd, hapd->own_addr, mask); if (res == 0) return 0; if (res < 0) { wpa_printf(MSG_ERROR, "Driver did not accept BSSID mask " MACSTR " for start address " MACSTR ".", MAC2STR(mask), MAC2STR(hapd->own_addr)); return -1; } for (i = 0; i < ETH_ALEN; i++) { if ((hapd->own_addr[i] & mask[i]) != hapd->own_addr[i]) { wpa_printf(MSG_ERROR, "Invalid BSSID mask " MACSTR " for start address " MACSTR ".", MAC2STR(mask), MAC2STR(hapd->own_addr)); wpa_printf(MSG_ERROR, "Start address must be the " "first address in the block (i.e., addr " "AND mask == addr)."); return -1; } } return 0;}static int mac_in_conf(struct hostapd_config *conf, const void *a){ size_t i; for (i = 0; i < conf->num_bss; i++) { if (hostapd_mac_comp(conf->bss[i].bssid, a) == 0) { return 1; } } return 0;}static 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); 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.get_seqnum_igtk = hostapd_wpa_auth_get_seqnum_igtk; 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; } return 0;}static int hostapd_setup_radius_srv(struct hostapd_data *hapd, struct hostapd_bss_config *conf){ struct radius_server_conf srv; os_memset(&srv, 0, sizeof(srv)); srv.client_file = conf->radius_server_clients; srv.auth_port = conf->radius_server_auth_port; srv.conf_ctx = conf; srv.eap_sim_db_priv = hapd->eap_sim_db_priv; srv.ssl_ctx = hapd->ssl_ctx; srv.pac_opaque_encr_key = conf->pac_opaque_encr_key; srv.eap_fast_a_id = conf->eap_fast_a_id; srv.eap_fast_a_id_len = conf->eap_fast_a_id_len; srv.eap_fast_a_id_info = conf->eap_fast_a_id_info; srv.eap_fast_prov = conf->eap_fast_prov; srv.pac_key_lifetime = conf->pac_key_lifetime; srv.pac_key_refresh_time = conf->pac_key_refresh_time; srv.eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind; srv.tnc = conf->tnc; srv.wps = hapd->wps; srv.ipv6 = conf->radius_server_ipv6; srv.get_eap_user = hostapd_radius_get_eap_user; srv.eap_req_id_text = conf->eap_req_id_text; srv.eap_req_id_text_len = conf->eap_req_id_text_len; hapd->radius_srv = radius_server_init(&srv); if (hapd->radius_srv == NULL) { wpa_printf(MSG_ERROR, "RADIUS server initialization failed."); return -1; } return 0;}/** * hostapd_setup_bss - Per-BSS setup (initialization) * @hapd: Pointer to BSS data * @first: Whether this BSS is the first BSS of an interface * * This function is used to initialize all per-BSS data structures and * resources. This gets called in a loop for each BSS when an interface is * initialized. Most of the modules that are initialized here will be * deinitialized in hostapd_cleanup(). */static int hostapd_setup_bss(struct hostapd_data *hapd, int first){ struct hostapd_bss_config *conf = hapd->conf; u8 ssid[HOSTAPD_MAX_SSID_LEN + 1]; int ssid_len, set_ssid; if (!first) { if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0) { /* Allocate the next available BSSID. */ do { inc_byte_array(hapd->own_addr, ETH_ALEN); } while (mac_in_conf(hapd->iconf, hapd->own_addr)); } else { /* Allocate the configured BSSID. */ os_memcpy(hapd->own_addr, hapd->conf->bssid, ETH_ALEN); if (hostapd_mac_comp(hapd->own_addr, hapd->iface->bss[0]->own_addr) == 0) { wpa_printf(MSG_ERROR, "BSS '%s' may not have " "BSSID set to the MAC address of " "the radio", hapd->conf->iface); return -1; } } hapd->interface_added = 1; if (hostapd_bss_add(hapd->iface->bss[0], hapd->conf->iface, hapd->own_addr)) { wpa_printf(MSG_ERROR, "Failed to add BSS (BSSID=" MACSTR ")", MAC2STR(hapd->own_addr)); return -1; } } /* * Fetch the SSID from the system and use it or, * if one was specified in the config file, verify they * match. */ ssid_len = hostapd_get_ssid(hapd, ssid, sizeof(ssid)); if (ssid_len < 0) { wpa_printf(MSG_ERROR, "Could not read SSID from system"); return -1; } if (conf->ssid.ssid_set) { /* * If SSID is specified in the config file and it differs * from what is being used then force installation of the * new SSID. */ set_ssid = (conf->ssid.ssid_len != (size_t) ssid_len || os_memcmp(conf->ssid.ssid, ssid, ssid_len) != 0); } else { /* * No SSID in the config file; just use the one we got * from the system. */ set_ssid = 0; conf->ssid.ssid_len = ssid_len; os_memcpy(conf->ssid.ssid, ssid, conf->ssid.ssid_len); conf->ssid.ssid[conf->ssid.ssid_len] = '\0'; } if (!hostapd_drv_none(hapd)) { wpa_printf(MSG_ERROR, "Using interface %s with hwaddr " MACSTR " and ssid '%s'", hapd->conf->iface, MAC2STR(hapd->own_addr), hapd->conf->ssid.ssid); } if (hostapd_setup_wpa_psk(conf)) { wpa_printf(MSG_ERROR, "WPA-PSK setup failed."); return -1; } /* Set flag for whether SSID is broadcast in beacons */ if (hostapd_set_broadcast_ssid(hapd, !!hapd->conf->ignore_broadcast_ssid)) { wpa_printf(MSG_ERROR, "Could not set broadcast SSID flag for " "kernel driver"); return -1; } if (hostapd_set_dtim_period(hapd, hapd->conf->dtim_period)) { wpa_printf(MSG_ERROR, "Could not set DTIM period for kernel " "driver"); return -1; } /* Set SSID for the kernel driver (to be used in beacon and probe * response frames) */ if (set_ssid && hostapd_set_ssid(hapd, (u8 *) conf->ssid.ssid, conf->ssid.ssid_len)) { wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver"); return -1; } if (wpa_debug_level == MSG_MSGDUMP) conf->radius->msg_dumps = 1; hapd->radius = radius_client_init(hapd, conf->radius); if (hapd->radius == NULL) { wpa_printf(MSG_ERROR, "RADIUS client initialization failed."); return -1; } if (hostapd_acl_init(hapd)) { wpa_printf(MSG_ERROR, "ACL initialization failed."); return -1; } if (hostapd_init_wps(hapd, conf)) 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; } if (hostapd_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; }#ifdef CONFIG_IEEE80211R if (!hostapd_drv_none(hapd)) { hapd->l2 = l2_packet_init(hapd->conf->iface, NULL, ETH_P_RRB, hostapd_rrb_receive, hapd, 0); 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 */ ieee802_11_set_beacon(hapd); if (conf->radius_server_clients && hostapd_setup_radius_srv(hapd, conf)) return -1; return 0;}static void hostapd_tx_queue_params(struct hostapd_iface *iface){ struct hostapd_data *hapd = iface->bss[0]; int i; struct hostapd_tx_queue_params *p; for (i = 0; i < NUM_TX_QUEUES; i++) { p = &iface->conf->tx_queue[i]; if (!p->configured) continue; if (hostapd_set_tx_queue_params(hapd, i, p->aifs, p->cwmin, p->cwmax, p->burst)) { wpa_printf(MSG_DEBUG, "Failed to set TX queue " "parameters for queue %d.", i); /* Continue anyway */ } }}static int hostapd_radius_get_eap_user(void *ctx, const u8 *identity, size_t identity_len, int phase2, struct eap_user *user){ const struct hostapd_eap_user *eap_user; int i, count; eap_user = hostapd_get_eap_user(ctx, identity, identity_len, phase2); if (eap_user == NULL) return -1; if (user == NULL) return 0; os_memset(user, 0, sizeof(*user)); count = EAP_USER_MAX_METHODS; if (count > EAP_MAX_METHODS) count = EAP_MAX_METHODS; for (i = 0; i < count; i++) { user->methods[i].vendor = eap_user->methods[i].vendor; user->methods[i].method = eap_user->methods[i].method; } if (eap_user->password) { user->password = os_malloc(eap_user->password_len); if (user->password == NULL) return -1; os_memcpy(user->password, eap_user->password, eap_user->password_len); user->password_len = eap_user->password_len; user->password_hash = eap_user->password_hash; } user->force_version = eap_user->force_version; user->ttls_auth = eap_user->ttls_auth; return 0;}static int setup_interface(struct hostapd_iface *iface){ struct hostapd_data *hapd = iface->bss[0]; struct hostapd_bss_config *conf = hapd->conf; size_t i; char country[4]; u8 *b = conf->bssid; int freq; size_t j; int ret = 0; u8 *prev_addr; /* * Initialize the driver interface and make sure that all BSSes get * configured with a pointer to this driver interface. */ if (b[0] | b[1] | b[2] | b[3] | b[4] | b[5]) { hapd->drv_priv = hostapd_driver_init_bssid(hapd, b);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?