eapol_test: Allow client IP address to be specified

Allow the user to set the IP address of the eapol_test client. This if
very useful when you have a machine with many interfaces and want to use a
particular one for testing RADIUS connectivity. For instance when I run the
national eduroam proxy I can only connect to other server from a particular
address, an our machine happens to have several IPs. So if I want to run
connectivity tests, I must make sure that my test uses a particular
interface. The -A option allows one to set this).

(jm: cleaned up to use radius configuration structure instead of global
variable for the address and added IPv6 support)
This commit is contained in:
Tomasz Wolniewicz 2008-03-30 18:15:52 +03:00 committed by Jouni Malinen
parent 1e4b9da10c
commit c454f57379
3 changed files with 83 additions and 8 deletions

View file

@ -738,15 +738,16 @@ radius_change_server(struct radius_client_data *radius,
struct hostapd_radius_server *oserv,
int sock, int sock6, int auth)
{
struct sockaddr_in serv;
struct sockaddr_in serv, claddr;
#ifdef CONFIG_IPV6
struct sockaddr_in6 serv6;
struct sockaddr_in6 serv6, claddr6;
#endif /* CONFIG_IPV6 */
struct sockaddr *addr;
socklen_t addrlen;
socklen_t addrlen, claddrlen;
char abuf[50];
int sel_sock;
struct radius_msg_list *entry;
struct hostapd_radius_servers *conf = radius->conf;
hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS,
HOSTAPD_LEVEL_INFO,
@ -816,11 +817,64 @@ radius_change_server(struct radius_client_data *radius,
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);
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);
claddrlen = sizeof(claddr6);
break;
#endif /* CONFIG_IPV6 */
default:
return -1;
}
if (bind(sel_sock, (struct sockaddr *) &claddr, claddrlen) < 0)
{
perror("bind[radius]");
return -1;
}
}
if (connect(sel_sock, addr, addrlen) < 0) {
perror("connect[radius]");
return -1;
}
#ifndef CONFIG_NATIVE_WINDOWS
switch (nserv->addr.af) {
case AF_INET:
claddrlen = sizeof(claddr);
getsockname(sel_sock, (struct sockaddr *) &claddr, &claddrlen);
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);
getsockname(sel_sock, (struct sockaddr *) &claddr6,
&claddrlen);
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