/*
* WPA Supplicant - testing driver interface
- * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
int test_socket;
struct sockaddr_un hostapd_addr;
int hostapd_addr_set;
+ struct sockaddr_in hostapd_addr_udp;
+ int hostapd_addr_udp_set;
char *own_socket_path;
char *test_dir;
u8 bssid[ETH_ALEN];
size_t assoc_wpa_ie_len;
int use_mlme;
int associated;
+ u8 *probe_req_ie;
+ size_t probe_req_ie_len;
};
struct dirent *dent;
DIR *dir;
struct sockaddr_un addr;
+ char cmd[512], *pos, *end;
+ int ret;
dir = opendir(path);
if (dir == NULL)
return;
+ end = cmd + sizeof(cmd);
+ pos = cmd;
+ ret = os_snprintf(pos, end - pos, "SCAN " MACSTR,
+ MAC2STR(drv->own_addr));
+ if (ret >= 0 && ret < end - pos)
+ pos += ret;
+ if (drv->probe_req_ie) {
+ ret = os_snprintf(pos, end - pos, " ");
+ if (ret >= 0 && ret < end - pos)
+ pos += ret;
+ pos += wpa_snprintf_hex(pos, end - pos, drv->probe_req_ie,
+ drv->probe_req_ie_len);
+ }
+ end[-1] = '\0';
+
while ((dent = readdir(dir))) {
if (os_strncmp(dent->d_name, "AP-", 3) != 0)
continue;
os_snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s",
path, dent->d_name);
- if (sendto(drv->test_socket, "SCAN", 4, 0,
+ if (sendto(drv->test_socket, cmd, os_strlen(cmd), 0,
(struct sockaddr *) &addr, sizeof(addr)) < 0) {
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_register_timeout(1, 0, wpa_driver_test_scan_timeout, drv,
drv->ctx);
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;
int ret;
end = cmd + sizeof(cmd);
pos += wpa_snprintf_hex(pos, end - pos, params->wpa_ie,
params->wpa_ie_len);
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,
sizeof(drv->hostapd_addr)) < 0) {
perror("sendto(test_socket)");
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);
drv->ssid_len = params->ssid_len;
os_free(drv->test_dir);
for (i = 0; i < MAX_SCAN_RESULTS; i++)
os_free(drv->scanres[i]);
+ os_free(drv->probe_req_ie);
os_free(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)
{
struct wpa_driver_test_data *drv = priv;
end = os_strchr(drv->test_dir, ' ');
if (end)
*end = '\0';
- wpa_driver_test_attach(drv, drv->test_dir);
- } else
- wpa_driver_test_attach(drv, NULL);
+ if (wpa_driver_test_attach(drv, drv->test_dir))
+ return -1;
+ } 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")) {
wpa_printf(MSG_DEBUG, "test_driver: Use AssocInfo events");
msg.msg_iovlen = 3;
if (os_memcmp(dest, drv->bssid, ETH_ALEN) == 0 ||
drv->test_dir == NULL) {
- msg.msg_name = &drv->hostapd_addr;
- msg.msg_namelen = sizeof(drv->hostapd_addr);
+ if (drv->hostapd_addr_udp_set) {
+ 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 {
struct stat st;
os_memset(&addr, 0, sizeof(addr));
#endif /* CONFIG_CLIENT_MLME */
+int wpa_driver_set_probe_req_ie(void *priv, const u8 *ies, size_t ies_len)
+{
+ struct wpa_driver_test_data *drv = priv;
+
+ os_free(drv->probe_req_ie);
+ if (ies) {
+ drv->probe_req_ie = os_malloc(ies_len);
+ if (drv->probe_req_ie == NULL) {
+ drv->probe_req_ie_len = 0;
+ return -1;
+ }
+ os_memcpy(drv->probe_req_ie, ies, ies_len);
+ drv->probe_req_ie_len = ies_len;
+ } else {
+ drv->probe_req_ie = NULL;
+ drv->probe_req_ie_len = 0;
+ }
+ return 0;
+}
+
+
const struct wpa_driver_ops wpa_driver_test_ops = {
"test",
"wpa_supplicant test driver",
NULL /* update_ft_ies */,
NULL /* send_ft_action */,
wpa_driver_test_get_scan_results2,
- NULL /* set_probe_req_ie */,
- NULL /* set_mode */
+ wpa_driver_set_probe_req_ie,
+ NULL /* set_mode */,
+ NULL /* set_country */
};