hostapd.c

来自「最新的Host AP 新添加了许多pcmcia 的驱动」· C语言 代码 · 共 2,028 行 · 第 1/4 页

C
2,028
字号
	} else {		hapd->drv_priv = hostapd_driver_init(hapd);	}	if (hapd->drv_priv == NULL) {		wpa_printf(MSG_ERROR, "%s driver initialization failed.",			   hapd->driver ? hapd->driver->name : "Unknown");		hapd->driver = NULL;		return -1;	}	for (i = 0; i < iface->num_bss; i++) {		iface->bss[i]->driver = hapd->driver;		iface->bss[i]->drv_priv = hapd->drv_priv;	}	if (hostapd_validate_bssid_configuration(iface))		return -1;#ifdef CONFIG_IEEE80211N	SET_2BIT_LE16(&iface->ht_op_mode,		      HT_INFO_OPERATION_MODE_OP_MODE_OFFSET,		      OP_MODE_PURE);#endif /* CONFIG_IEEE80211N */	if (hapd->iconf->country[0] && hapd->iconf->country[1]) {		os_memcpy(country, hapd->iconf->country, 3);		country[3] = '\0';		if (hostapd_set_country(hapd, country) < 0) {			wpa_printf(MSG_ERROR, "Failed to set country code");			return -1;		}	}	if (hapd->iconf->ieee80211d &&	    hostapd_set_ieee80211d(hapd, 1) < 0) {		wpa_printf(MSG_ERROR, "Failed to set ieee80211d (%d)",			   hapd->iconf->ieee80211d);		return -1;	}	if (hapd->iconf->bridge_packets != INTERNAL_BRIDGE_DO_NOT_CONTROL &&	    hostapd_set_internal_bridge(hapd, hapd->iconf->bridge_packets)) {		wpa_printf(MSG_ERROR, "Failed to set bridge_packets for "			   "kernel driver");		return -1;	}	/* TODO: merge with hostapd_driver_init() ? */	if (hostapd_wireless_event_init(hapd) < 0)		return -1;	if (hostapd_get_hw_features(iface)) {		/* Not all drivers support this yet, so continue without hw		 * feature data. */	} else {		int ret = hostapd_select_hw_mode(iface);		if (ret < 0) {			wpa_printf(MSG_ERROR, "Could not select hw_mode and "				   "channel. (%d)", ret);			return -1;		}	}	hostapd_flush_old_stations(hapd);	hostapd_set_privacy(hapd, 0);	if (hapd->iconf->channel) {		freq = hostapd_hw_get_freq(hapd, hapd->iconf->channel);		wpa_printf(MSG_DEBUG, "Mode: %s  Channel: %d  "			   "Frequency: %d MHz",			   hostapd_hw_mode_txt(hapd->iconf->hw_mode),			   hapd->iconf->channel, freq);		if (hostapd_set_freq(hapd, hapd->iconf->hw_mode, freq,				     hapd->iconf->ieee80211n,				     hapd->iconf->secondary_channel)) {			wpa_printf(MSG_ERROR, "Could not set channel for "				   "kernel driver");			return -1;		}	}	hostapd_broadcast_wep_clear(hapd);	if (hostapd_setup_encryption(hapd->conf->iface, hapd))		return -1;	hostapd_set_beacon_int(hapd, hapd->iconf->beacon_int);	ieee802_11_set_beacon(hapd);	if (hapd->iconf->rts_threshold > -1 &&	    hostapd_set_rts(hapd, hapd->iconf->rts_threshold)) {		wpa_printf(MSG_ERROR, "Could not set RTS threshold for "			   "kernel driver");		return -1;	}	if (hapd->iconf->fragm_threshold > -1 &&	    hostapd_set_frag(hapd, hapd->iconf->fragm_threshold)) {		wpa_printf(MSG_ERROR, "Could not set fragmentation threshold "			   "for kernel driver");		return -1;	}	prev_addr = hapd->own_addr;	for (j = 0; j < iface->num_bss; j++) {		hapd = iface->bss[j];		if (j)			os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN);		if (hostapd_setup_bss(hapd, j == 0))			return -1;		if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0)			prev_addr = hapd->own_addr;	}	hostapd_tx_queue_params(iface);	ap_list_init(iface);	if (hostapd_driver_commit(hapd) < 0) {		wpa_printf(MSG_ERROR, "%s: Failed to commit driver "			   "configuration", __func__);		return -1;	}	return ret;}/** * hostapd_setup_interface - Setup of an interface * @iface: Pointer to interface data. * Returns: 0 on success, -1 on failure * * Initializes the driver interface, validates the configuration, * and sets driver parameters based on the configuration. * Flushes old stations, sets the channel, encryption, * beacons, and WDS links based on the configuration. */static int hostapd_setup_interface(struct hostapd_iface *iface){	int ret;	ret = setup_interface(iface);	if (ret) {		wpa_printf(MSG_DEBUG, "%s: Unable to setup interface.",			   iface->bss[0]->conf->iface);		eloop_terminate();		return -1;	} else if (!hostapd_drv_none(iface->bss[0])) {		wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",			   iface->bss[0]->conf->iface);	}	return 0;}static void show_version(void){	fprintf(stderr,		"hostapd v" VERSION_STR "\n"		"User space daemon for IEEE 802.11 AP management,\n"		"IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator\n"		"Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi> "		"and contributors\n");}static void usage(void){	show_version();	fprintf(stderr,		"\n"		"usage: hostapd [-hdBKtv] [-P <PID file>] "		"<configuration file(s)>\n"		"\n"		"options:\n"		"   -h   show this usage\n"		"   -d   show more debug messages (-dd for even more)\n"		"   -B   run daemon in the background\n"		"   -P   PID file\n"		"   -K   include key data in debug messages\n"		"   -t   include timestamps in some debug messages\n"		"   -v   show hostapd version\n");	exit(1);}/** * hostapd_alloc_bss_data - Allocate and initialize per-BSS data * @hapd_iface: Pointer to interface data * @conf: Pointer to per-interface configuration * @bss: Pointer to per-BSS configuration for this BSS * Returns: Pointer to allocated BSS data * * This function is used to allocate per-BSS data structure. This data will be * freed after hostapd_cleanup() is called for it during interface * deinitialization. */static struct hostapd_data *hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface,		       struct hostapd_config *conf,		       struct hostapd_bss_config *bss){	struct hostapd_data *hapd;	hapd = os_zalloc(sizeof(*hapd));	if (hapd == NULL)		return NULL;	hapd->iconf = conf;	hapd->conf = bss;	hapd->iface = hapd_iface;	if (hapd->conf->individual_wep_key_len > 0) {		/* use key0 in individual key and key1 in broadcast key */		hapd->default_wep_key_idx = 1;	}#ifdef EAP_TLS_FUNCS	if (hapd->conf->eap_server &&	    (hapd->conf->ca_cert || hapd->conf->server_cert ||	     hapd->conf->dh_file)) {		struct tls_connection_params params;		hapd->ssl_ctx = tls_init(NULL);		if (hapd->ssl_ctx == NULL) {			wpa_printf(MSG_ERROR, "Failed to initialize TLS");			goto fail;		}		os_memset(&params, 0, sizeof(params));		params.ca_cert = hapd->conf->ca_cert;		params.client_cert = hapd->conf->server_cert;		params.private_key = hapd->conf->private_key;		params.private_key_passwd = hapd->conf->private_key_passwd;		params.dh_file = hapd->conf->dh_file;		if (tls_global_set_params(hapd->ssl_ctx, &params)) {			wpa_printf(MSG_ERROR, "Failed to set TLS parameters");			goto fail;		}		if (tls_global_set_verify(hapd->ssl_ctx,					  hapd->conf->check_crl)) {			wpa_printf(MSG_ERROR, "Failed to enable check_crl");			goto fail;		}	}#endif /* EAP_TLS_FUNCS */#ifdef EAP_SERVER	if (hapd->conf->eap_sim_db) {		hapd->eap_sim_db_priv =			eap_sim_db_init(hapd->conf->eap_sim_db,					hostapd_sim_db_cb, hapd);		if (hapd->eap_sim_db_priv == NULL) {			wpa_printf(MSG_ERROR, "Failed to initialize EAP-SIM "				   "database interface");			goto fail;		}	}#endif /* EAP_SERVER */	hapd->driver = hapd->iconf->driver;	return hapd;#if defined(EAP_TLS_FUNCS) || defined(EAP_SERVER)fail:#endif	/* TODO: cleanup allocated resources(?) */	os_free(hapd);	return NULL;}/** * hostapd_init - Allocate and initialize per-interface data * @config_file: Path to the configuration file * Returns: Pointer to the allocated interface data or %NULL on failure * * This function is used to allocate main data structures for per-interface * data. The allocated data buffer will be freed by calling * hostapd_cleanup_iface(). */static struct hostapd_iface * hostapd_init(const char *config_file){	struct hostapd_iface *hapd_iface = NULL;	struct hostapd_config *conf = NULL;	struct hostapd_data *hapd;	size_t i;	hapd_iface = os_zalloc(sizeof(*hapd_iface));	if (hapd_iface == NULL)		goto fail;	hapd_iface->config_fname = os_strdup(config_file);	if (hapd_iface->config_fname == NULL)		goto fail;	conf = hostapd_config_read(hapd_iface->config_fname);	if (conf == NULL)		goto fail;	hapd_iface->conf = conf;	hapd_iface->num_bss = conf->num_bss;	hapd_iface->bss = os_zalloc(conf->num_bss *				    sizeof(struct hostapd_data *));	if (hapd_iface->bss == NULL)		goto fail;	for (i = 0; i < conf->num_bss; i++) {		hapd = hapd_iface->bss[i] =			hostapd_alloc_bss_data(hapd_iface, conf,					       &conf->bss[i]);		if (hapd == NULL)			goto fail;	}	return hapd_iface;fail:	if (conf)		hostapd_config_free(conf);	if (hapd_iface) {		for (i = 0; hapd_iface->bss && i < hapd_iface->num_bss; i++) {			hapd = hapd_iface->bss[i];			if (hapd && hapd->ssl_ctx)				tls_deinit(hapd->ssl_ctx);		}		os_free(hapd_iface->config_fname);		os_free(hapd_iface->bss);		os_free(hapd_iface);	}	return NULL;}int main(int argc, char *argv[]){	struct hapd_interfaces interfaces;	int ret = 1, k;	size_t i, j;	int c, debug = 0, daemonize = 0, tnc = 0;	const char *pid_file = NULL;	hostapd_logger_register_cb(hostapd_logger_cb);	for (;;) {		c = getopt(argc, argv, "BdhKP:tv");		if (c < 0)			break;		switch (c) {		case 'h':			usage();			break;		case 'd':			debug++;			if (wpa_debug_level > 0)				wpa_debug_level--;			break;		case 'B':			daemonize++;			break;		case 'K':			wpa_debug_show_keys++;			break;		case 'P':			pid_file = optarg;			break;		case 't':			wpa_debug_timestamp++;			break;		case 'v':			show_version();			exit(1);			break;		default:			usage();			break;		}	}	if (optind == argc)		usage();	if (eap_server_register_methods()) {		wpa_printf(MSG_ERROR, "Failed to register EAP methods");		return -1;	}	interfaces.count = argc - optind;	interfaces.iface = os_malloc(interfaces.count *				     sizeof(struct hostapd_iface *));	if (interfaces.iface == NULL) {		wpa_printf(MSG_ERROR, "malloc failed\n");		return -1;	}	if (eloop_init(&interfaces)) {		wpa_printf(MSG_ERROR, "Failed to initialize event loop");		return -1;	}#ifndef CONFIG_NATIVE_WINDOWS	eloop_register_signal(SIGHUP, handle_reload, NULL);	eloop_register_signal(SIGUSR1, handle_dump_state, NULL);#endif /* CONFIG_NATIVE_WINDOWS */	eloop_register_signal_terminate(handle_term, NULL);	/* Initialize interfaces */	for (i = 0; i < interfaces.count; i++) {		wpa_printf(MSG_ERROR, "Configuration file: %s",			   argv[optind + i]);		interfaces.iface[i] = hostapd_init(argv[optind + i]);		if (!interfaces.iface[i])			goto out;		for (k = 0; k < debug; k++) {			if (interfaces.iface[i]->bss[0]->conf->			    logger_stdout_level > 0)				interfaces.iface[i]->bss[0]->conf->					logger_stdout_level--;		}		ret = hostapd_setup_interface(interfaces.iface[i]);		if (ret)			goto out;		for (k = 0; k < (int) interfaces.iface[i]->num_bss; k++) {			if (interfaces.iface[i]->bss[0]->conf->tnc)				tnc++;		}	}#ifdef EAP_TNC	if (tnc && tncs_global_init() < 0) {		wpa_printf(MSG_ERROR, "Failed to initialize TNCS");		goto out;	}#endif /* EAP_TNC */	if (daemonize && os_daemonize(pid_file)) {		perror("daemon");		goto out;	}#ifndef CONFIG_NATIVE_WINDOWS	openlog("hostapd", 0, LOG_DAEMON);#endif /* CONFIG_NATIVE_WINDOWS */	eloop_run();	/* Disconnect associated stations from all interfaces and BSSes */	for (i = 0; i < interfaces.count; i++) {		for (j = 0; j < interfaces.iface[i]->num_bss; j++) {			struct hostapd_data *hapd =				interfaces.iface[i]->bss[j];			hostapd_free_stas(hapd);			hostapd_flush_old_stations(hapd);		}	}	ret = 0; out:	/* Deinitialize all interfaces */	for (i = 0; i < interfaces.count; i++) {		if (!interfaces.iface[i])			continue;		hostapd_cleanup_iface_pre(interfaces.iface[i]);		for (j = 0; j < interfaces.iface[i]->num_bss; j++) {			struct hostapd_data *hapd =				interfaces.iface[i]->bss[j];			hostapd_cleanup(hapd);			if (j == interfaces.iface[i]->num_bss - 1 &&			    hapd->driver)				hostapd_driver_deinit(hapd);		}		for (j = 0; j < interfaces.iface[i]->num_bss; j++)			os_free(interfaces.iface[i]->bss[j]);		hostapd_cleanup_iface(interfaces.iface[i]);	}	os_free(interfaces.iface);#ifdef EAP_TNC	tncs_global_deinit();#endif /* EAP_TNC */	eloop_destroy();#ifndef CONFIG_NATIVE_WINDOWS	closelog();#endif /* CONFIG_NATIVE_WINDOWS */	eap_server_unregister_methods();	os_daemonize_terminate(pid_file);	return ret;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?