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 + -
显示快捷键?