/**
 * config_reload2 - Part 2 of configuration reloading
 * @hapd_iface:
 */
static void config_reload2(struct hostapd_iface *hapd_iface, int status)
{
	struct hostapd_config_change *change = hapd_iface->change;
	struct hostapd_data *hapd = change->hapd;
	struct hostapd_config *newconf = change->newconf;
	struct hostapd_config *oldconf = change->oldconf;
	int beacon_changed = change->beacon_changed;
	struct hostapd_data **new_hapd = change->new_hapd;
	struct hostapd_data **old_hapd = change->old_hapd;
	int num_old_hapd = change->num_old_hapd;
	size_t i, j, max_bss, same_bssid;
	struct hostapd_bss_config *newbss, *oldbss;
	u8 *prev_addr;
	hostapd_iface_cb cb;

	free(change);
	hapd_iface->change = NULL;

	if (status) {
		printf("Failed to setup new interface config\n");

		cb = hapd_iface->config_reload_cb;
		hapd_iface->config_reload_cb = NULL;

		/* Invalid configuration - cleanup and terminate hostapd */
		hapd_iface->bss = old_hapd;
		hapd_iface->num_bss = num_old_hapd;
		hapd_iface->conf = hapd->iconf = oldconf;
		hapd->conf = &oldconf->bss[0];
		hostapd_config_free(newconf);
		free(new_hapd);

		cb(hapd_iface, -2);

		return;
	}

	/*
	 * If any BSSes have been removed, added, or had their BSSIDs changed,
	 * completely remove and reinitialize such BSSes and all the BSSes
	 * following them since their BSSID might have changed.
	 */
	max_bss = oldconf->num_bss;
	if (max_bss > newconf->num_bss)
		max_bss = newconf->num_bss;

	for (i = 0; i < max_bss; i++) {
		if (strcmp(oldconf->bss[i].iface, newconf->bss[i].iface) != 0
		    || hostapd_mac_comp(oldconf->bss[i].bssid,
					newconf->bss[i].bssid) != 0)
			break;
	}
	same_bssid = i;

	for (i = 0; i < oldconf->num_bss; i++) {
		oldbss = &oldconf->bss[i];
		newbss = NULL;
		for (j = 0; j < newconf->num_bss; j++) {
			if (strcmp(oldbss->iface, newconf->bss[j].iface) == 0)
			{
				newbss = &newconf->bss[j];
				break;
			}
		}

		if (newbss && i < same_bssid) {
			hapd = hapd_iface->bss[j] = old_hapd[i];
			hapd->iconf = newconf;
			hapd->conf = newbss;
			hostapd_reconfig_bss(hapd, newbss, oldbss, oldconf,
					     beacon_changed);
		} else {
			hapd = old_hapd[i];
			HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
				      "Removing BSS (ifname %s)\n",
				      hapd->conf->iface);
			hostapd_free_stas(hapd);
			/* Send broadcast deauthentication for this BSS, but do
			 * not clear all STAs from the driver since other BSSes
			 * may have STA entries. The driver will remove all STA
			 * entries for this BSS anyway when the interface is
			 * being removed. */
#if 0
			hostapd_deauth_all_stas(hapd);
			hostapd_cleanup(hapd);
#endif

			free(hapd);
		}
	}


	prev_addr = hapd_iface->bss[0]->own_addr;
	hapd = hapd_iface->bss[0];
	for (j = 0; j < newconf->num_bss; j++) {
		if (hapd_iface->bss[j] != NULL) {
			prev_addr = hapd_iface->bss[j]->own_addr;
			continue;
		}

		newbss = &newconf->bss[j];

		HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "Reconfiguration: adding "
			      "new BSS (ifname=%s)\n", newbss->iface);

#if 0
		hapd = hapd_iface->bss[j] =
			hostapd_alloc_bss_data(hapd_iface, newconf, newbss);
#endif
		if (hapd == NULL) {
			printf("Failed to initialize new BSS\n");
			/* FIX: This one is somewhat hard to recover
			 * from.. Would need to remove this BSS from
			 * conf and BSS list. */
			exit(1);
		}
		hapd->driver = hapd_iface->bss[0]->driver;
		hapd->iface = hapd_iface;
		hapd->iconf = newconf;
		hapd->conf = newbss;

		memcpy(hapd->own_addr, prev_addr, ETH_ALEN);
		if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0)
			prev_addr = hapd->own_addr;

#if 0
		if (hostapd_setup_bss(hapd, j == 0)) {
			printf("Failed to setup new BSS\n");
			/* FIX */
			exit(1);
		}
#endif

	}

	free(old_hapd);
	hostapd_config_free(oldconf);

	cb = hapd_iface->config_reload_cb;
	hapd_iface->config_reload_cb = NULL;

	cb(hapd_iface, 0);
}
Example #2
0
int main(int argc, char *argv[])
{
	struct hapd_interfaces interfaces;
	int ret = 1, i, j;
	int c, debug = 0, daemonize = 0;

	for (;;) {
		c = getopt(argc, argv, "Bdh");
		if (c < 0)
			break;
		switch (c) {
		case 'h':
			usage();
			break;
		case 'd':
			debug++;
			break;
		case 'B':
			daemonize++;
			break;

		default:
			usage();
			break;
		}
	}

	if (optind == argc)
		usage();

	interfaces.count = argc - optind;

	interfaces.hapd = malloc(interfaces.count * sizeof(hostapd *));
	if (interfaces.hapd == NULL) {
		printf("malloc failed\n");
		exit(1);
	}

	eloop_init(&interfaces);
	eloop_register_signal(SIGHUP, handle_reload, NULL);
	eloop_register_signal(SIGINT, handle_term, NULL);
	eloop_register_signal(SIGTERM, handle_term, NULL);
	eloop_register_signal(SIGUSR1, handle_dump_state, NULL);

	for (i = 0; i < interfaces.count; i++) {
		printf("Configuration file: %s\n", argv[optind + i]);
		interfaces.hapd[i] = hostapd_init(argv[optind + i]);
		if (!interfaces.hapd[i])
			goto out;
		for (j = 0; j < debug; j++) {
			if (interfaces.hapd[i]->conf->logger_stdout_level > 0)
				interfaces.hapd[i]->conf->
					logger_stdout_level--;
			interfaces.hapd[i]->conf->debug++;
		}
		hostapd_set_broadcast_wep(interfaces.hapd[i]);
		if (hostapd_setup_interface(interfaces.hapd[i]))
			goto out;
	}

	if (daemonize && daemon(0, 0)) {
		perror("daemon");
		goto out;
	}

	openlog("hostapd", 0, LOG_DAEMON);

	eloop_run();

	for (i = 0; i < interfaces.count; i++) {
		hostapd_free_stas(interfaces.hapd[i]);
		hostapd_flush_old_stations(interfaces.hapd[i]);
	}

	ret = 0;

 out:
	for (i = 0; i < interfaces.count; i++) {
		if (!interfaces.hapd[i])
			continue;

		hostapd_cleanup(interfaces.hapd[i]);
		free(interfaces.hapd[i]);
	}
	free(interfaces.hapd);

	eloop_destroy();

	closelog();

	return ret;
}
Example #3
0
int main(int argc, char *argv[])
{
	struct hapd_interfaces interfaces;
	int ret = 1, i, j;
	int c, debug = 0, daemonize = 0;
#ifdef JUMPSTART
	char *js_passwd = NULL;
#endif	

	for (;;) {
		c = getopt(argc, argv, "BdhKtvj:");
		if (c < 0)
			break;
		switch (c) {
		case 'h':
			usage();
			break;
		case 'd':
			debug++;
			break;
		case 'B':
			daemonize++;
			break;
		case 'K':
			wpa_debug_show_keys++;
			break;
		case 't':
			wpa_debug_timestamp++;
			break;
		case 'v':
			show_version();
			exit(1);
			break;
#ifdef JUMPSTART
		case 'j':
			js_passwd = optarg;
			break;
#endif
		default:
			usage();
			break;
		}
	}

	if (optind == argc)
		usage();

	register_drivers();		/* NB: generated by Makefile */

	interfaces.count = argc - optind;

	interfaces.hapd = malloc(interfaces.count * sizeof(hostapd *));
	if (interfaces.hapd == NULL) {
		printf("malloc failed\n");
		exit(1);
	}

	eloop_init(&interfaces);
	eloop_register_signal(SIGHUP, handle_reload, NULL);
	eloop_register_signal(SIGINT, handle_term, NULL);
	eloop_register_signal(SIGTERM, handle_term, NULL);
	eloop_register_signal(SIGUSR1, handle_dump_state, NULL);

	for (i = 0; i < interfaces.count; i++) {
		printf("Configuration file: %s\n", argv[optind + i]);
#ifdef JUMPSTART
		interfaces.hapd[i] = hostapd_init(argv[optind + i], js_passwd);
#else
		interfaces.hapd[i] = hostapd_init(argv[optind + i]);
#endif
		if (!interfaces.hapd[i])
			goto out;
		for (j = 0; j < debug; j++) {
			if (interfaces.hapd[i]->conf->logger_stdout_level > 0)
				interfaces.hapd[i]->conf->
					logger_stdout_level--;
			interfaces.hapd[i]->conf->debug++;
		}
		if (hostapd_setup_interface(interfaces.hapd[i]))
			goto out;
		wpa_debug_level -= interfaces.hapd[0]->conf->debug;
	}

	if (daemonize && daemon(0, 0)) {
		perror("daemon");
		goto out;
	}

	openlog("hostapd", 0, LOG_DAEMON);

	eloop_run();

	for (i = 0; i < interfaces.count; i++) {
		hostapd_free_stas(interfaces.hapd[i]);
		hostapd_flush_old_stations(interfaces.hapd[i]);
	}

	ret = 0;

 out:
	for (i = 0; i < interfaces.count; i++) {
		if (!interfaces.hapd[i])
			continue;

		hostapd_cleanup(interfaces.hapd[i]);
		free(interfaces.hapd[i]);
	}
	free(interfaces.hapd);

	eloop_destroy();

	closelog();

	driver_unregister_all();

	return ret;
}