driver_test: Optional support for using UDP socket
driver_test can now be used either over UNIX domain socket or UDP socket. This makes it possible to run the test over network and makes it easier to port driver_test to Windows. hostapd configuration: test_socket=UDP:<listen port> wpa_supplicant configuration: driver_param=test_udp=<dst IP addr>:<port>
This commit is contained in:
parent
2ff0f83b9e
commit
e33bbd8f4d
4 changed files with 123 additions and 20 deletions
|
@ -16,6 +16,7 @@ ChangeLog for hostapd
|
||||||
* fixed WEP authentication (both Open System and Shared Key) with
|
* fixed WEP authentication (both Open System and Shared Key) with
|
||||||
mac80211
|
mac80211
|
||||||
* added support for EAP-AKA' (draft-arkko-eap-aka-kdf)
|
* added support for EAP-AKA' (draft-arkko-eap-aka-kdf)
|
||||||
|
* added support for using driver_test over UDP socket
|
||||||
|
|
||||||
2008-11-23 - v0.6.6
|
2008-11-23 - v0.6.6
|
||||||
* added a new configuration option, wpa_ptk_rekey, that can be used to
|
* added a new configuration option, wpa_ptk_rekey, that can be used to
|
||||||
|
|
|
@ -61,6 +61,7 @@ struct test_driver_data {
|
||||||
struct test_driver_bss *bss;
|
struct test_driver_bss *bss;
|
||||||
char *socket_dir;
|
char *socket_dir;
|
||||||
char *own_socket_path;
|
char *own_socket_path;
|
||||||
|
int udp_port;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1142,7 +1143,10 @@ static int test_driver_sta_add(const char *ifname, void *priv, const u8 *addr,
|
||||||
static void * test_driver_init(struct hostapd_data *hapd)
|
static void * test_driver_init(struct hostapd_data *hapd)
|
||||||
{
|
{
|
||||||
struct test_driver_data *drv;
|
struct test_driver_data *drv;
|
||||||
struct sockaddr_un addr;
|
struct sockaddr_un addr_un;
|
||||||
|
struct sockaddr_in addr_in;
|
||||||
|
struct sockaddr *addr;
|
||||||
|
socklen_t alen;
|
||||||
|
|
||||||
drv = os_zalloc(sizeof(struct test_driver_data));
|
drv = os_zalloc(sizeof(struct test_driver_data));
|
||||||
if (drv == NULL) {
|
if (drv == NULL) {
|
||||||
|
@ -1169,7 +1173,8 @@ static void * test_driver_init(struct hostapd_data *hapd)
|
||||||
memcpy(drv->bss->bssid, hapd->own_addr, ETH_ALEN);
|
memcpy(drv->bss->bssid, hapd->own_addr, ETH_ALEN);
|
||||||
|
|
||||||
if (hapd->conf->test_socket) {
|
if (hapd->conf->test_socket) {
|
||||||
if (strlen(hapd->conf->test_socket) >= sizeof(addr.sun_path)) {
|
if (strlen(hapd->conf->test_socket) >=
|
||||||
|
sizeof(addr_un.sun_path)) {
|
||||||
printf("Too long test_socket path\n");
|
printf("Too long test_socket path\n");
|
||||||
test_driver_free_priv(drv);
|
test_driver_free_priv(drv);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1184,30 +1189,43 @@ static void * test_driver_init(struct hostapd_data *hapd)
|
||||||
hapd->conf->test_socket + 4,
|
hapd->conf->test_socket + 4,
|
||||||
MAC2STR(hapd->own_addr));
|
MAC2STR(hapd->own_addr));
|
||||||
}
|
}
|
||||||
|
} else if (strncmp(hapd->conf->test_socket, "UDP:", 4) == 0) {
|
||||||
|
drv->udp_port = atoi(hapd->conf->test_socket + 4);
|
||||||
} else {
|
} else {
|
||||||
drv->own_socket_path = strdup(hapd->conf->test_socket);
|
drv->own_socket_path = strdup(hapd->conf->test_socket);
|
||||||
}
|
}
|
||||||
if (drv->own_socket_path == NULL) {
|
if (drv->own_socket_path == NULL && drv->udp_port == 0) {
|
||||||
test_driver_free_priv(drv);
|
test_driver_free_priv(drv);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
drv->test_socket = socket(PF_UNIX, SOCK_DGRAM, 0);
|
drv->test_socket = socket(drv->udp_port ? PF_INET : PF_UNIX,
|
||||||
|
SOCK_DGRAM, 0);
|
||||||
if (drv->test_socket < 0) {
|
if (drv->test_socket < 0) {
|
||||||
perror("socket(PF_UNIX)");
|
perror("socket");
|
||||||
test_driver_free_priv(drv);
|
test_driver_free_priv(drv);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&addr, 0, sizeof(addr));
|
if (drv->udp_port) {
|
||||||
addr.sun_family = AF_UNIX;
|
os_memset(&addr_in, 0, sizeof(addr_in));
|
||||||
os_strlcpy(addr.sun_path, drv->own_socket_path,
|
addr_in.sin_family = AF_INET;
|
||||||
sizeof(addr.sun_path));
|
addr_in.sin_port = htons(drv->udp_port);
|
||||||
if (bind(drv->test_socket, (struct sockaddr *) &addr,
|
addr = (struct sockaddr *) &addr_in;
|
||||||
sizeof(addr)) < 0) {
|
alen = sizeof(addr_in);
|
||||||
|
} else {
|
||||||
|
os_memset(&addr_un, 0, sizeof(addr_un));
|
||||||
|
addr_un.sun_family = AF_UNIX;
|
||||||
|
os_strlcpy(addr_un.sun_path, drv->own_socket_path,
|
||||||
|
sizeof(addr_un.sun_path));
|
||||||
|
addr = (struct sockaddr *) &addr_un;
|
||||||
|
alen = sizeof(addr_un);
|
||||||
|
}
|
||||||
|
if (bind(drv->test_socket, addr, alen) < 0) {
|
||||||
perror("bind(PF_UNIX)");
|
perror("bind(PF_UNIX)");
|
||||||
close(drv->test_socket);
|
close(drv->test_socket);
|
||||||
unlink(drv->own_socket_path);
|
if (drv->own_socket_path)
|
||||||
|
unlink(drv->own_socket_path);
|
||||||
test_driver_free_priv(drv);
|
test_driver_free_priv(drv);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1235,7 +1253,8 @@ static void test_driver_deinit(void *priv)
|
||||||
if (drv->test_socket >= 0) {
|
if (drv->test_socket >= 0) {
|
||||||
eloop_unregister_read_sock(drv->test_socket);
|
eloop_unregister_read_sock(drv->test_socket);
|
||||||
close(drv->test_socket);
|
close(drv->test_socket);
|
||||||
unlink(drv->own_socket_path);
|
if (drv->own_socket_path)
|
||||||
|
unlink(drv->own_socket_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* There should be only one BSS remaining at this point. */
|
/* There should be only one BSS remaining at this point. */
|
||||||
|
|
|
@ -31,6 +31,8 @@ struct wpa_driver_test_data {
|
||||||
int test_socket;
|
int test_socket;
|
||||||
struct sockaddr_un hostapd_addr;
|
struct sockaddr_un hostapd_addr;
|
||||||
int hostapd_addr_set;
|
int hostapd_addr_set;
|
||||||
|
struct sockaddr_in hostapd_addr_udp;
|
||||||
|
int hostapd_addr_udp_set;
|
||||||
char *own_socket_path;
|
char *own_socket_path;
|
||||||
char *test_dir;
|
char *test_dir;
|
||||||
u8 bssid[ETH_ALEN];
|
u8 bssid[ETH_ALEN];
|
||||||
|
@ -145,6 +147,13 @@ static int wpa_driver_test_scan(void *priv, const u8 *ssid, size_t ssid_len)
|
||||||
perror("sendto(test_socket)");
|
perror("sendto(test_socket)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (drv->test_socket >= 0 && drv->hostapd_addr_udp_set &&
|
||||||
|
sendto(drv->test_socket, "SCAN", 4, 0,
|
||||||
|
(struct sockaddr *) &drv->hostapd_addr_udp,
|
||||||
|
sizeof(drv->hostapd_addr_udp)) < 0) {
|
||||||
|
perror("sendto(test_socket)");
|
||||||
|
}
|
||||||
|
|
||||||
eloop_cancel_timeout(wpa_driver_test_scan_timeout, drv, drv->ctx);
|
eloop_cancel_timeout(wpa_driver_test_scan_timeout, drv, drv->ctx);
|
||||||
eloop_register_timeout(1, 0, wpa_driver_test_scan_timeout, drv,
|
eloop_register_timeout(1, 0, wpa_driver_test_scan_timeout, drv,
|
||||||
drv->ctx);
|
drv->ctx);
|
||||||
|
@ -242,7 +251,8 @@ static int wpa_driver_test_associate(
|
||||||
drv->hostapd_addr_set = 1;
|
drv->hostapd_addr_set = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drv->test_socket >= 0 && drv->hostapd_addr_set) {
|
if (drv->test_socket >= 0 &&
|
||||||
|
(drv->hostapd_addr_set || drv->hostapd_addr_udp_set)) {
|
||||||
char cmd[200], *pos, *end;
|
char cmd[200], *pos, *end;
|
||||||
int ret;
|
int ret;
|
||||||
end = cmd + sizeof(cmd);
|
end = cmd + sizeof(cmd);
|
||||||
|
@ -259,12 +269,20 @@ static int wpa_driver_test_associate(
|
||||||
pos += wpa_snprintf_hex(pos, end - pos, params->wpa_ie,
|
pos += wpa_snprintf_hex(pos, end - pos, params->wpa_ie,
|
||||||
params->wpa_ie_len);
|
params->wpa_ie_len);
|
||||||
end[-1] = '\0';
|
end[-1] = '\0';
|
||||||
if (sendto(drv->test_socket, cmd, os_strlen(cmd), 0,
|
if (drv->hostapd_addr_set &&
|
||||||
|
sendto(drv->test_socket, cmd, os_strlen(cmd), 0,
|
||||||
(struct sockaddr *) &drv->hostapd_addr,
|
(struct sockaddr *) &drv->hostapd_addr,
|
||||||
sizeof(drv->hostapd_addr)) < 0) {
|
sizeof(drv->hostapd_addr)) < 0) {
|
||||||
perror("sendto(test_socket)");
|
perror("sendto(test_socket)");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (drv->hostapd_addr_udp_set &&
|
||||||
|
sendto(drv->test_socket, cmd, os_strlen(cmd), 0,
|
||||||
|
(struct sockaddr *) &drv->hostapd_addr_udp,
|
||||||
|
sizeof(drv->hostapd_addr_udp)) < 0) {
|
||||||
|
perror("sendto(test_socket)");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
os_memcpy(drv->ssid, params->ssid, params->ssid_len);
|
os_memcpy(drv->ssid, params->ssid, params->ssid_len);
|
||||||
drv->ssid_len = params->ssid_len;
|
drv->ssid_len = params->ssid_len;
|
||||||
|
@ -640,6 +658,50 @@ static int wpa_driver_test_attach(struct wpa_driver_test_data *drv,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpa_driver_test_attach_udp(struct wpa_driver_test_data *drv,
|
||||||
|
char *dst)
|
||||||
|
{
|
||||||
|
char *pos;
|
||||||
|
|
||||||
|
pos = os_strchr(dst, ':');
|
||||||
|
if (pos == NULL)
|
||||||
|
return -1;
|
||||||
|
*pos++ = '\0';
|
||||||
|
wpa_printf(MSG_DEBUG, "%s: addr=%s port=%s", __func__, dst, pos);
|
||||||
|
|
||||||
|
drv->test_socket = socket(PF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (drv->test_socket < 0) {
|
||||||
|
perror("socket(PF_INET)");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
os_memset(&drv->hostapd_addr_udp, 0, sizeof(drv->hostapd_addr_udp));
|
||||||
|
drv->hostapd_addr_udp.sin_family = AF_INET;
|
||||||
|
#if defined(CONFIG_NATIVE_WINDOWS) || defined(CONFIG_ANSI_C_EXTRA)
|
||||||
|
{
|
||||||
|
int a[4];
|
||||||
|
u8 *pos;
|
||||||
|
sscanf(dst, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]);
|
||||||
|
pos = (u8 *) &drv->hostapd_addr_udp.sin_addr;
|
||||||
|
*pos++ = a[0];
|
||||||
|
*pos++ = a[1];
|
||||||
|
*pos++ = a[2];
|
||||||
|
*pos++ = a[3];
|
||||||
|
}
|
||||||
|
#else /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */
|
||||||
|
inet_aton(dst, &drv->hostapd_addr_udp.sin_addr);
|
||||||
|
#endif /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */
|
||||||
|
drv->hostapd_addr_udp.sin_port = htons(atoi(pos));
|
||||||
|
|
||||||
|
drv->hostapd_addr_udp_set = 1;
|
||||||
|
|
||||||
|
eloop_register_read_sock(drv->test_socket,
|
||||||
|
wpa_driver_test_receive_unix, drv, NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int wpa_driver_test_set_param(void *priv, const char *param)
|
static int wpa_driver_test_set_param(void *priv, const char *param)
|
||||||
{
|
{
|
||||||
struct wpa_driver_test_data *drv = priv;
|
struct wpa_driver_test_data *drv = priv;
|
||||||
|
@ -677,9 +739,24 @@ static int wpa_driver_test_set_param(void *priv, const char *param)
|
||||||
end = os_strchr(drv->test_dir, ' ');
|
end = os_strchr(drv->test_dir, ' ');
|
||||||
if (end)
|
if (end)
|
||||||
*end = '\0';
|
*end = '\0';
|
||||||
wpa_driver_test_attach(drv, drv->test_dir);
|
if (wpa_driver_test_attach(drv, drv->test_dir))
|
||||||
} else
|
return -1;
|
||||||
wpa_driver_test_attach(drv, NULL);
|
} else {
|
||||||
|
pos = os_strstr(param, "test_udp=");
|
||||||
|
if (pos) {
|
||||||
|
char *dst, *epos;
|
||||||
|
dst = os_strdup(pos + 9);
|
||||||
|
if (dst == NULL)
|
||||||
|
return -1;
|
||||||
|
epos = os_strchr(dst, ' ');
|
||||||
|
if (epos)
|
||||||
|
*epos = '\0';
|
||||||
|
if (wpa_driver_test_attach_udp(drv, dst))
|
||||||
|
return -1;
|
||||||
|
os_free(dst);
|
||||||
|
} else if (wpa_driver_test_attach(drv, NULL))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (os_strstr(param, "use_associnfo=1")) {
|
if (os_strstr(param, "use_associnfo=1")) {
|
||||||
wpa_printf(MSG_DEBUG, "test_driver: Use AssocInfo events");
|
wpa_printf(MSG_DEBUG, "test_driver: Use AssocInfo events");
|
||||||
|
@ -733,8 +810,13 @@ static int wpa_driver_test_send_eapol(void *priv, const u8 *dest, u16 proto,
|
||||||
msg.msg_iovlen = 3;
|
msg.msg_iovlen = 3;
|
||||||
if (os_memcmp(dest, drv->bssid, ETH_ALEN) == 0 ||
|
if (os_memcmp(dest, drv->bssid, ETH_ALEN) == 0 ||
|
||||||
drv->test_dir == NULL) {
|
drv->test_dir == NULL) {
|
||||||
msg.msg_name = &drv->hostapd_addr;
|
if (drv->hostapd_addr_udp_set) {
|
||||||
msg.msg_namelen = sizeof(drv->hostapd_addr);
|
msg.msg_name = &drv->hostapd_addr_udp;
|
||||||
|
msg.msg_namelen = sizeof(drv->hostapd_addr_udp);
|
||||||
|
} else {
|
||||||
|
msg.msg_name = &drv->hostapd_addr;
|
||||||
|
msg.msg_namelen = sizeof(drv->hostapd_addr);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
os_memset(&addr, 0, sizeof(addr));
|
os_memset(&addr, 0, sizeof(addr));
|
||||||
|
|
|
@ -11,6 +11,7 @@ ChangeLog for wpa_supplicant
|
||||||
file); new wpa_cli commands wps_pin, wps_pbc, and wps_reg are used to
|
file); new wpa_cli commands wps_pin, wps_pbc, and wps_reg are used to
|
||||||
manage WPS negotiation; see README-WPS for more details
|
manage WPS negotiation; see README-WPS for more details
|
||||||
* added support for EAP-AKA' (draft-arkko-eap-aka-kdf)
|
* added support for EAP-AKA' (draft-arkko-eap-aka-kdf)
|
||||||
|
* added support for using driver_test over UDP socket
|
||||||
|
|
||||||
2008-11-23 - v0.6.6
|
2008-11-23 - v0.6.6
|
||||||
* added Milenage SIM/USIM emulator for EAP-SIM/EAP-AKA
|
* added Milenage SIM/USIM emulator for EAP-SIM/EAP-AKA
|
||||||
|
|
Loading…
Reference in a new issue