コード例 #1
0
static void handle_reload(int sig, void *eloop_ctx, void *signal_ctx)
{
	struct hapd_interfaces *hapds = (struct hapd_interfaces *) eloop_ctx;
	struct hostapd_config *newconf;
	int i;

	printf("Signal %d received - reloading configuration\n", sig);

	for (i = 0; i < hapds->count; i++) {
		hostapd *hapd = hapds->hapd[i];
		newconf = hostapd_config_read(hapd->config_fname);
		if (newconf == NULL) {
			printf("Failed to read new configuration file - "
			       "continuing with old.\n");
			continue;
		}
		/* TODO: update dynamic data based on changed configuration
		 * items (e.g., open/close sockets, remove stations added to
		 * deny list, etc.) */
		radius_client_flush(hapd->radius);
		hostapd_config_free(hapd->conf);
		hapd->conf = newconf;
#ifdef JUMPSTART
		hostapd_setup_interface(hapd);
#endif /* JUMSTART */
	}
}
コード例 #2
0
ファイル: hostapd.c プロジェクト: hbl0307106015/OWM
int hostapd_reload_config(struct hostapd_iface *iface)
{
	struct hostapd_data *hapd = iface->bss[0];
	struct hostapd_config *newconf, *oldconf;
	size_t j;

	if (iface->interfaces == NULL ||
	    iface->interfaces->config_read_cb == NULL)
		return -1;
	newconf = iface->interfaces->config_read_cb(iface->config_fname);
	if (newconf == NULL)
		return -1;

	/*
	 * Deauthenticate all stations since the new configuration may not
	 * allow them to use the BSS anymore.
	 */
	for (j = 0; j < iface->num_bss; j++) {
		hostapd_flush_old_stations(iface->bss[j],
					   WLAN_REASON_PREV_AUTH_NOT_VALID);
		hostapd_broadcast_wep_clear(iface->bss[j]);

#ifndef CONFIG_NO_RADIUS
		/* TODO: update dynamic data based on changed configuration
		 * items (e.g., open/close sockets, etc.) */
		radius_client_flush(iface->bss[j]->radius, 0);
#endif /* CONFIG_NO_RADIUS */
	}

	oldconf = hapd->iconf;
	iface->conf = newconf;

	hostapd_select_hw_mode(iface);
	iface->freq = hostapd_hw_get_freq(hapd, newconf->channel);

	if (hostapd_set_freq(hapd, newconf->hw_mode, iface->freq,
			     newconf->channel,
			     newconf->ieee80211n,
			     newconf->secondary_channel)) {
		wpa_printf(MSG_ERROR, "Could not set channel for "
			   "kernel driver");
	}

	if (iface->current_mode)
		hostapd_prepare_rates(iface, iface->current_mode);

	for (j = 0; j < iface->num_bss; j++) {
		hapd = iface->bss[j];
		hapd->iconf = newconf;
		hapd->conf = &newconf->bss[j];
		hostapd_reload_bss(hapd);
	}

	hostapd_config_free(oldconf);


	return 0;
}
コード例 #3
0
static int
radius_change_server(struct radius_client_data *radius,
                     struct hostapd_radius_server *nserv,
                     struct hostapd_radius_server *oserv,
                     int sock, int auth)
{
    struct hostapd_data *hapd = radius->hapd;
    struct sockaddr_in serv;

    hostapd_logger(hapd, NULL, HOSTAPD_MODULE_RADIUS, HOSTAPD_LEVEL_INFO,
                   "%s server %s:%d",
                   auth ? "Authentication" : "Accounting",
                   inet_ntoa(nserv->addr), nserv->port);

    if (!oserv || nserv->shared_secret_len != oserv->shared_secret_len ||
            memcmp(nserv->shared_secret, oserv->shared_secret,
                   nserv->shared_secret_len) != 0) {
        /* Pending RADIUS packets used different shared
         * secret, so they would need to be modified. Could
         * update all message authenticators and
         * User-Passwords, etc. and retry with new server. For
         * now, just drop all pending packets. */
        radius_client_flush(radius);
    } else {
        /* Reset retry counters for the new server */
        struct radius_msg_list *entry;
        entry = radius->msgs;
        while (entry) {
            entry->next_try = entry->first_try +
                              RADIUS_CLIENT_FIRST_WAIT;
            entry->attempts = 0;
            entry->next_wait = RADIUS_CLIENT_FIRST_WAIT * 2;
            entry = entry->next;
        }
        if (radius->msgs) {
            eloop_cancel_timeout(radius_client_timer, radius,
                                 NULL);
            eloop_register_timeout(RADIUS_CLIENT_FIRST_WAIT, 0,
                                   radius_client_timer, radius,
                                   NULL);
        }
    }

    memset(&serv, 0, sizeof(serv));
    serv.sin_family = AF_INET;
    serv.sin_addr.s_addr = nserv->addr.s_addr;
    serv.sin_port = htons(nserv->port);

    if (connect(sock, (struct sockaddr *) &serv, sizeof(serv)) < 0) {
        perror("connect[radius]");
        return -1;
    }

    return 0;
}
コード例 #4
0
void radius_client_deinit(struct radius_client_data *radius)
{
	if (!radius)
		return;

	eloop_cancel_timeout(radius_retry_primary_timer, radius, NULL);
	radius_client_flush(radius);
	free(radius->auth_handlers);
	free(radius->acct_handlers);
	free(radius);
}
コード例 #5
0
void radius_client_deinit(hostapd *hapd)
{
	if (!hapd->radius)
		return;

	eloop_cancel_timeout(radius_retry_primary_timer, hapd, NULL);

	radius_client_flush(hapd);
	free(hapd->radius->auth_handlers);
	free(hapd->radius->acct_handlers);
	free(hapd->radius);
	hapd->radius = NULL;
}
コード例 #6
0
ファイル: radius_client.c プロジェクト: OPSF/uClinux
void radius_client_deinit(struct wpa_supplicant *wpa_s)
{
	if (!wpa_s->radius)
		return;

	eloop_cancel_timeout(radius_retry_primary_timer, wpa_s, NULL);

	radius_client_flush(wpa_s);
	free(wpa_s->radius->auth_handlers);
	free(wpa_s->radius->acct_handlers);
	free(wpa_s->radius);
	wpa_s->radius = NULL;
}
void radius_client_deinit(struct radius_client_data *radius)
{
	if (!radius)
		return;

	if (radius->auth_serv_sock >= 0)
		eloop_unregister_read_sock(radius->auth_serv_sock);
	if (radius->acct_serv_sock >= 0)
		eloop_unregister_read_sock(radius->acct_serv_sock);

	eloop_cancel_timeout(radius_retry_primary_timer, radius, NULL);

	radius_client_flush(radius, 0);
	os_free(radius->auth_handlers);
	os_free(radius->acct_handlers);
	os_free(radius);
}
コード例 #8
0
ファイル: hostapd.c プロジェクト: edwacode/qca-hostap
int hostapd_reload_config(struct hostapd_iface *iface)
{
	struct hostapd_data *hapd = iface->bss[0];
	struct hostapd_config *newconf, *oldconf;
	size_t j;

	if (iface->config_read_cb == NULL)
		return -1;
	newconf = iface->config_read_cb(iface->config_fname);
	if (newconf == NULL)
		return -1;

	/*
	 * Deauthenticate all stations since the new configuration may not
	 * allow them to use the BSS anymore.
	 */
	for (j = 0; j < iface->num_bss; j++) {
		hostapd_flush_old_stations(iface->bss[j],
					   WLAN_REASON_PREV_AUTH_NOT_VALID);
		hostapd_broadcast_wep_clear(iface->bss[j]);

#ifndef CONFIG_NO_RADIUS
		/* TODO: update dynamic data based on changed configuration
		 * items (e.g., open/close sockets, etc.) */
		radius_client_flush(iface->bss[j]->radius, 0);
#endif /* CONFIG_NO_RADIUS */
	}

	oldconf = hapd->iconf;
	iface->conf = newconf;

	for (j = 0; j < iface->num_bss; j++) {
		hapd = iface->bss[j];
		hapd->iconf = newconf;
		hapd->conf = &newconf->bss[j];
		hostapd_reload_bss(hapd);
	}

	hostapd_config_free(oldconf);


	return 0;
}
コード例 #9
0
ファイル: hostapd.c プロジェクト: Zauberstuhl/ot_6015x
static void hostapd_clear_old(struct hostapd_iface *iface)
{
	size_t j;

	/*
	 * Deauthenticate all stations since the new configuration may not
	 * allow them to use the BSS anymore.
	 */
	for (j = 0; j < iface->num_bss; j++) {
		hostapd_flush_old_stations(iface->bss[j],
					   WLAN_REASON_PREV_AUTH_NOT_VALID);
		hostapd_broadcast_wep_clear(iface->bss[j]);

#ifndef CONFIG_NO_RADIUS
		/* TODO: update dynamic data based on changed configuration
		 * items (e.g., open/close sockets, etc.) */
		radius_client_flush(iface->bss[j]->radius, 0);
#endif /* CONFIG_NO_RADIUS */
	}
}
コード例 #10
0
struct radius_client_data *
radius_client_reconfig(struct radius_client_data *old, void *ctx,
		       struct hostapd_radius_servers *oldconf,
		       struct hostapd_radius_servers *newconf)
{
	radius_client_flush(old, 0);

	if (newconf->retry_primary_interval !=
	    oldconf->retry_primary_interval ||
	    newconf->num_auth_servers != oldconf->num_auth_servers ||
	    newconf->num_acct_servers != oldconf->num_acct_servers ||
	    radius_servers_diff(newconf->auth_servers, oldconf->auth_servers,
				newconf->num_auth_servers) ||
	    radius_servers_diff(newconf->acct_servers, oldconf->acct_servers,
				newconf->num_acct_servers)) {
		hostapd_logger(ctx, NULL, HOSTAPD_MODULE_RADIUS,
			       HOSTAPD_LEVEL_DEBUG,
			       "Reconfiguring RADIUS client");
		radius_client_deinit(old);
		return radius_client_init(ctx, newconf);
	}

	return old;
}
コード例 #11
0
static int
radius_change_server(struct radius_client_data *radius,
		     struct hostapd_radius_server *nserv,
		     struct hostapd_radius_server *oserv,
		     int sock, int sock6, int auth)
{
	struct sockaddr_in serv, claddr;
#ifdef CONFIG_IPV6
	struct sockaddr_in6 serv6, claddr6;
#endif /* CONFIG_IPV6 */
	struct sockaddr *addr, *cl_addr;
	socklen_t addrlen, claddrlen;
	char abuf[50];
	int sel_sock;
	struct radius_msg_list *entry;
	struct hostapd_radius_servers *conf = radius->conf;
	struct sockaddr_in disconnect_addr = {
		.sin_family = AF_UNSPEC,
	};

	hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS,
		       HOSTAPD_LEVEL_INFO,
		       "%s server %s:%d",
		       auth ? "Authentication" : "Accounting",
		       hostapd_ip_txt(&nserv->addr, abuf, sizeof(abuf)),
		       nserv->port);

	if (oserv && oserv == nserv) {
		/* Reconnect to same server, flush */
		if (auth)
			radius_client_flush(radius, 1);
	}

	if (oserv && oserv != nserv &&
	    (nserv->shared_secret_len != oserv->shared_secret_len ||
	     os_memcmp(nserv->shared_secret, oserv->shared_secret,
		       nserv->shared_secret_len) != 0)) {
		/* Pending RADIUS packets used different shared secret, so
		 * they need to be modified. Update accounting message
		 * authenticators here. Authentication messages are removed
		 * since they would require more changes and the new RADIUS
		 * server may not be prepared to receive them anyway due to
		 * missing state information. Client will likely retry
		 * authentication, so this should not be an issue. */
		if (auth)
			radius_client_flush(radius, 1);
		else {
			radius_client_update_acct_msgs(
				radius, nserv->shared_secret,
				nserv->shared_secret_len);
		}
	}

	/* Reset retry counters for the new server */
	for (entry = radius->msgs; oserv && oserv != nserv && entry;
	     entry = entry->next) {
		if ((auth && entry->msg_type != RADIUS_AUTH) ||
		    (!auth && entry->msg_type != RADIUS_ACCT))
			continue;
		entry->next_try = entry->first_try + RADIUS_CLIENT_FIRST_WAIT;
		entry->attempts = 0;
		entry->next_wait = RADIUS_CLIENT_FIRST_WAIT * 2;
	}

	if (radius->msgs) {
		eloop_cancel_timeout(radius_client_timer, radius, NULL);
		eloop_register_timeout(RADIUS_CLIENT_FIRST_WAIT, 0,
				       radius_client_timer, radius, NULL);
	}

	switch (nserv->addr.af) {
	case AF_INET:
		os_memset(&serv, 0, sizeof(serv));
		serv.sin_family = AF_INET;
		serv.sin_addr.s_addr = nserv->addr.u.v4.s_addr;
		serv.sin_port = htons(nserv->port);
		addr = (struct sockaddr *) &serv;
		addrlen = sizeof(serv);
		sel_sock = sock;
		break;
#ifdef CONFIG_IPV6
	case AF_INET6:
		os_memset(&serv6, 0, sizeof(serv6));
		serv6.sin6_family = AF_INET6;
		os_memcpy(&serv6.sin6_addr, &nserv->addr.u.v6,
			  sizeof(struct in6_addr));
		serv6.sin6_port = htons(nserv->port);
		addr = (struct sockaddr *) &serv6;
		addrlen = sizeof(serv6);
		sel_sock = sock6;
		break;
#endif /* CONFIG_IPV6 */
	default:
		return -1;
	}

	if (sel_sock < 0) {
		wpa_printf(MSG_INFO,
			   "RADIUS: No server socket available (af=%d sock=%d sock6=%d auth=%d",
			   nserv->addr.af, sock, sock6, auth);
		return -1;
	}

	if (conf->force_client_addr) {
		switch (conf->client_addr.af) {
		case AF_INET:
			os_memset(&claddr, 0, sizeof(claddr));
			claddr.sin_family = AF_INET;
			claddr.sin_addr.s_addr = conf->client_addr.u.v4.s_addr;
			claddr.sin_port = htons(0);
			cl_addr = (struct sockaddr *) &claddr;
			claddrlen = sizeof(claddr);
			break;
#ifdef CONFIG_IPV6
		case AF_INET6:
			os_memset(&claddr6, 0, sizeof(claddr6));
			claddr6.sin6_family = AF_INET6;
			os_memcpy(&claddr6.sin6_addr, &conf->client_addr.u.v6,
				  sizeof(struct in6_addr));
			claddr6.sin6_port = htons(0);
			cl_addr = (struct sockaddr *) &claddr6;
			claddrlen = sizeof(claddr6);
			break;
#endif /* CONFIG_IPV6 */
		default:
			return -1;
		}

		if (bind(sel_sock, cl_addr, claddrlen) < 0) {
			wpa_printf(MSG_INFO, "bind[radius]: %s",
				   strerror(errno));
			return -1;
		}
	}

	/* Force a reconnect by disconnecting the socket first */
	if (connect(sel_sock, (struct sockaddr *) &disconnect_addr,
		    sizeof(disconnect_addr)) < 0)
		wpa_printf(MSG_INFO, "disconnect[radius]: %s", strerror(errno));

	if (connect(sel_sock, addr, addrlen) < 0) {
		wpa_printf(MSG_INFO, "connect[radius]: %s", strerror(errno));
		return -1;
	}

#ifndef CONFIG_NATIVE_WINDOWS
	switch (nserv->addr.af) {
	case AF_INET:
		claddrlen = sizeof(claddr);
		if (getsockname(sel_sock, (struct sockaddr *) &claddr,
				&claddrlen) == 0) {
			wpa_printf(MSG_DEBUG, "RADIUS local address: %s:%u",
				   inet_ntoa(claddr.sin_addr),
				   ntohs(claddr.sin_port));
		}
		break;
#ifdef CONFIG_IPV6
	case AF_INET6: {
		claddrlen = sizeof(claddr6);
		if (getsockname(sel_sock, (struct sockaddr *) &claddr6,
				&claddrlen) == 0) {
			wpa_printf(MSG_DEBUG, "RADIUS local address: %s:%u",
				   inet_ntop(AF_INET6, &claddr6.sin6_addr,
					     abuf, sizeof(abuf)),
				   ntohs(claddr6.sin6_port));
		}
		break;
	}
#endif /* CONFIG_IPV6 */
	}
#endif /* CONFIG_NATIVE_WINDOWS */

	if (auth)
		radius->auth_sock = sel_sock;
	else
		radius->acct_sock = sel_sock;

	return 0;
}
static int
radius_change_server(struct radius_client_data *radius,
		     struct hostapd_radius_server *nserv,
		     struct hostapd_radius_server *oserv,
		     int sock, int sock6, int auth)
{
	struct sockaddr_in serv;
#ifdef CONFIG_IPV6
	struct sockaddr_in6 serv6;
#endif /* CONFIG_IPV6 */
	struct sockaddr *addr;
	socklen_t addrlen;
	char abuf[50];
	int sel_sock;
	struct radius_msg_list *entry;

	hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS,
		       HOSTAPD_LEVEL_INFO,
		       "%s server %s:%d",
		       auth ? "Authentication" : "Accounting",
		       hostapd_ip_txt(&nserv->addr, abuf, sizeof(abuf)),
		       nserv->port);

	if (!oserv || nserv->shared_secret_len != oserv->shared_secret_len ||
	    os_memcmp(nserv->shared_secret, oserv->shared_secret,
		      nserv->shared_secret_len) != 0) {
		/* Pending RADIUS packets used different shared secret, so
		 * they need to be modified. Update accounting message
		 * authenticators here. Authentication messages are removed
		 * since they would require more changes and the new RADIUS
		 * server may not be prepared to receive them anyway due to
		 * missing state information. Client will likely retry
		 * authentication, so this should not be an issue. */
		if (auth)
			radius_client_flush(radius, 1);
		else {
			radius_client_update_acct_msgs(
				radius, nserv->shared_secret,
				nserv->shared_secret_len);
		}
	}

	/* Reset retry counters for the new server */
	for (entry = radius->msgs; entry; entry = entry->next) {
		if ((auth && entry->msg_type != RADIUS_AUTH) ||
		    (!auth && entry->msg_type != RADIUS_ACCT))
			continue;
		entry->next_try = entry->first_try + RADIUS_CLIENT_FIRST_WAIT;
		entry->attempts = 0;
		entry->next_wait = RADIUS_CLIENT_FIRST_WAIT * 2;
	}

	if (radius->msgs) {
		eloop_cancel_timeout(radius_client_timer, radius, NULL);
		eloop_register_timeout(RADIUS_CLIENT_FIRST_WAIT, 0,
				       radius_client_timer, radius, NULL);
	}

	switch (nserv->addr.af) {
	case AF_INET:
		os_memset(&serv, 0, sizeof(serv));
		serv.sin_family = AF_INET;
		serv.sin_addr.s_addr = nserv->addr.u.v4.s_addr;
		serv.sin_port = htons(nserv->port);
		addr = (struct sockaddr *) &serv;
		addrlen = sizeof(serv);
		sel_sock = sock;
		break;
#ifdef CONFIG_IPV6
	case AF_INET6:
		os_memset(&serv6, 0, sizeof(serv6));
		serv6.sin6_family = AF_INET6;
		os_memcpy(&serv6.sin6_addr, &nserv->addr.u.v6,
			  sizeof(struct in6_addr));
		serv6.sin6_port = htons(nserv->port);
		addr = (struct sockaddr *) &serv6;
		addrlen = sizeof(serv6);
		sel_sock = sock6;
		break;
#endif /* CONFIG_IPV6 */
	default:
		return -1;
	}

	if (connect(sel_sock, addr, addrlen) < 0) {
		perror("connect[radius]");
		return -1;
	}

	if (auth)
		radius->auth_sock = sel_sock;
	else
		radius->acct_sock = sel_sock;

	return 0;
}
static void hostapd_reconfig_bss(struct hostapd_data *hapd,
				 struct hostapd_bss_config *newbss,
				 struct hostapd_bss_config *oldbss,
				 struct hostapd_config *oldconf,
				 int beacon_changed)
{
	struct hostapd_config_change change;
	int encr_changed = 0;
	struct radius_client_data *old_radius;

	radius_client_flush(hapd->radius, 0);

	if (hostapd_set_dtim_period(hapd, newbss->dtim_period))
		printf("Could not set DTIM period for kernel driver\n");

	if (newbss->ssid.ssid_len != oldbss->ssid.ssid_len ||
	    memcmp(newbss->ssid.ssid, oldbss->ssid.ssid,
		   newbss->ssid.ssid_len) != 0) {
		if (hostapd_set_ssid(hapd, (u8 *) newbss->ssid.ssid,
				     newbss->ssid.ssid_len))
			printf("Could not set SSID for kernel driver\n");
		beacon_changed++;
	}

	if (newbss->ignore_broadcast_ssid != oldbss->ignore_broadcast_ssid)
		beacon_changed++;

	if (hostapd_wep_key_cmp(&newbss->ssid.wep, &oldbss->ssid.wep)) {
		encr_changed++;
		beacon_changed++;
	}

	vlan_reconfig(hapd, oldconf, oldbss);

	if (beacon_changed) {
		HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "Updating beacon frame "
			      "information\n");
		ieee802_11_set_beacon(hapd);
	}

	change.hapd = hapd;
	change.oldconf = oldconf;
	change.newconf = hapd->iconf;
	change.oldbss = oldbss;
	change.newbss = newbss;
	change.mac_acl_changed = hostapd_acl_diff(newbss, oldbss);
	if (newbss->max_num_sta != oldbss->max_num_sta &&
	    newbss->max_num_sta < hapd->num_sta) {
		change.num_sta_remove = hapd->num_sta - newbss->max_num_sta;
	} else
		change.num_sta_remove = 0;
	ap_for_each_sta(hapd, hostapd_config_reload_sta, &change);

	old_radius = hapd->radius;
	hapd->radius = radius_client_reconfig(hapd->radius, hapd,
					      oldbss->radius, newbss->radius);
	hapd->radius_client_reconfigured = old_radius != hapd->radius ||
		hostapd_ip_diff(&newbss->own_ip_addr, &oldbss->own_ip_addr);

	ieee802_1x_reconfig(hapd, oldconf, oldbss);
	iapp_reconfig(hapd, oldconf, oldbss);

	hostapd_acl_reconfig(hapd, oldconf);
	accounting_reconfig(hapd, oldconf);
}
コード例 #14
0
static int
radius_change_server(struct radius_client_data *radius,
		     struct hostapd_radius_server *nserv,
		     struct hostapd_radius_server *oserv,
		     int sock, int sock6, int auth)
{
	struct sockaddr_in serv;
#ifdef CONFIG_IPV6
	struct sockaddr_in6 serv6;
#endif /* CONFIG_IPV6 */
	struct sockaddr *addr;
	socklen_t addrlen;
	char abuf[50];
	int sel_sock;

	hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS,
		       HOSTAPD_LEVEL_INFO,
		       "%s server %s:%d",
		       auth ? "Authentication" : "Accounting",
		       hostapd_ip_txt(&nserv->addr, abuf, sizeof(abuf)),
		       nserv->port);

	if (!oserv || nserv->shared_secret_len != oserv->shared_secret_len ||
	    memcmp(nserv->shared_secret, oserv->shared_secret,
		   nserv->shared_secret_len) != 0) {
		/* Pending RADIUS packets used different shared
		 * secret, so they would need to be modified. Could
		 * update all message authenticators and
		 * User-Passwords, etc. and retry with new server. For
		 * now, just drop all pending packets. */
		radius_client_flush(radius);
	} else {
		/* Reset retry counters for the new server */
		struct radius_msg_list *entry;
		entry = radius->msgs;
		while (entry) {
			entry->next_try = entry->first_try +
				RADIUS_CLIENT_FIRST_WAIT;
			entry->attempts = 0;
			entry->next_wait = RADIUS_CLIENT_FIRST_WAIT * 2;
			entry = entry->next;
		}
		if (radius->msgs) {
			eloop_cancel_timeout(radius_client_timer, radius,
					     NULL);
			eloop_register_timeout(RADIUS_CLIENT_FIRST_WAIT, 0,
					       radius_client_timer, radius,
					       NULL);
		}
	}

	switch (nserv->addr.af) {
	case AF_INET:
		memset(&serv, 0, sizeof(serv));
		serv.sin_family = AF_INET;
		serv.sin_addr.s_addr = nserv->addr.u.v4.s_addr;
		serv.sin_port = htons(nserv->port);
		addr = (struct sockaddr *) &serv;
		addrlen = sizeof(serv);
		sel_sock = sock;
		break;
#ifdef CONFIG_IPV6
	case AF_INET6:
		memset(&serv6, 0, sizeof(serv6));
		serv6.sin6_family = AF_INET6;
		memcpy(&serv6.sin6_addr, &nserv->addr.u.v6,
		       sizeof(struct in6_addr));
		serv6.sin6_port = htons(nserv->port);
		addr = (struct sockaddr *) &serv6;
		addrlen = sizeof(serv6);
		sel_sock = sock6;
		break;
#endif /* CONFIG_IPV6 */
	default:
		return -1;
	}

	if (connect(sel_sock, addr, addrlen) < 0) {
		perror("connect[radius]");
		return -1;
	}

	if (auth)
		radius->auth_sock = sel_sock;
	else
		radius->acct_sock = sel_sock;

	return 0;
}