#include "driver.h"
#include "l2_packet/l2_packet.h"
#include "eloop.h"
-#include "sha1.h"
-#include "ieee802_11_defs.h"
-
-
-#ifdef HOSTAPD
+#include "crypto/sha1.h"
+#include "common/ieee802_11_defs.h"
#include "../../hostapd/hostapd.h"
-#include "../../hostapd/config.h"
#include "../../hostapd/wpa.h"
-#include "../../hostapd/hw_features.h"
-#include "../../hostapd/wps_hostapd.h"
struct test_client_socket {
int privacy;
};
-struct test_driver_data {
- struct hostapd_data *hapd;
- struct test_client_socket *cli;
- int test_socket;
- struct test_driver_bss *bss;
- char *socket_dir;
- char *own_socket_path;
- int udp_port;
-};
-
-#else /* HOSTAPD */
-
struct wpa_driver_test_global {
int dummy;
};
size_t probe_req_ie_len;
int ibss;
int privacy;
+ int ap;
+
+ struct hostapd_data *hapd;
+ struct test_client_socket *cli;
+ struct test_driver_bss *bss;
+ int udp_port;
};
-#endif /* HOSTAPD */
+static void wpa_driver_test_deinit(void *priv);
+static int wpa_driver_test_attach(struct wpa_driver_test_data *drv,
+ const char *dir, int ap);
+static void wpa_driver_test_close_test_socket(
+ struct wpa_driver_test_data *drv);
+
+#ifdef CONFIG_AP
+void ap_mgmt_rx(void *ctx, u8 *buf, size_t len, u16 stype,
+ struct hostapd_frame_info *fi);
+void ap_mgmt_tx_cb(void *ctx, u8 *buf, size_t len, u16 stype, int ok);
+
+#else /* CONFIG_AP */
+#ifndef HOSTAPD
+static inline void ap_mgmt_rx(void *ctx, u8 *buf, size_t len, u16 stype,
+ struct hostapd_frame_info *fi)
+{
+}
+
+static inline void ap_mgmt_tx_cb(void *ctx, u8 *buf, size_t len, u16 stype,
+ int ok)
+{
+}
+#endif /* HOSTAPD */
+#endif /* CONFIG_AP */
-#ifdef HOSTAPD
static void test_driver_free_bss(struct test_driver_bss *bss)
{
}
-static void test_driver_free_priv(struct test_driver_data *drv)
+static void test_driver_free_bsses(struct wpa_driver_test_data *drv)
{
- struct test_driver_bss *bss, *prev;
-
- if (drv == NULL)
- return;
+ struct test_driver_bss *bss, *prev_bss;
bss = drv->bss;
while (bss) {
- prev = bss;
+ prev_bss = bss;
bss = bss->next;
- test_driver_free_bss(prev);
+ test_driver_free_bss(prev_bss);
}
- free(drv->own_socket_path);
- free(drv->socket_dir);
- free(drv);
+
+ drv->bss = NULL;
}
static struct test_client_socket *
-test_driver_get_cli(struct test_driver_data *drv, struct sockaddr_un *from,
+test_driver_get_cli(struct wpa_driver_test_data *drv, struct sockaddr_un *from,
socklen_t fromlen)
{
struct test_client_socket *cli = drv->cli;
size_t data_len, int encrypt,
const u8 *own_addr)
{
- struct test_driver_data *drv = priv;
+ struct wpa_driver_test_data *drv = priv;
struct test_client_socket *cli;
struct msghdr msg;
struct iovec io[3];
static int test_driver_send_ether(void *priv, const u8 *dst, const u8 *src,
u16 proto, const u8 *data, size_t data_len)
{
- struct test_driver_data *drv = priv;
+ struct wpa_driver_test_data *drv = priv;
struct msghdr msg;
struct iovec io[3];
struct l2_ethhdr eth;
DIR *dir;
int ret = 0, broadcast = 0, count = 0;
- if (drv->test_socket < 0 || drv->socket_dir == NULL) {
+ if (drv->test_socket < 0 || drv->test_dir == NULL) {
wpa_printf(MSG_DEBUG, "%s: invalid parameters (sock=%d "
- "socket_dir=%p)",
- __func__, drv->test_socket, drv->socket_dir);
+ "test_dir=%p)",
+ __func__, drv->test_socket, drv->test_dir);
return -1;
}
msg.msg_iov = io;
msg.msg_iovlen = 3;
- dir = opendir(drv->socket_dir);
+ dir = opendir(drv->test_dir);
if (dir == NULL) {
perror("test_driver: opendir");
return -1;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s",
- drv->socket_dir, dent->d_name);
+ drv->test_dir, dent->d_name);
if (strcmp(addr.sun_path, drv->own_socket_path) == 0)
continue;
}
-static int test_driver_send_mgmt_frame(void *priv, const void *buf, size_t len)
+static int wpa_driver_test_send_mlme(void *priv, const u8 *data,
+ size_t data_len)
{
- struct test_driver_data *drv = priv;
+ struct wpa_driver_test_data *drv = priv;
struct msghdr msg;
struct iovec io[2];
const u8 *dest;
- int ret = 0, broadcast = 0;
- char desttxt[30];
struct sockaddr_un addr;
struct dirent *dent;
DIR *dir;
+ int broadcast;
+ int ret = 0;
struct ieee80211_hdr *hdr;
u16 fc;
+#ifdef HOSTAPD
+ char desttxt[30];
+#endif /* HOSTAPD */
- if (drv->test_socket < 0 || len < 10 || drv->socket_dir == NULL) {
+ wpa_hexdump(MSG_MSGDUMP, "test_send_mlme", data, data_len);
+ if (drv->test_socket < 0 || data_len < 10) {
wpa_printf(MSG_DEBUG, "%s: invalid parameters (sock=%d len=%lu"
- " socket_dir=%p)",
- __func__, drv->test_socket, (unsigned long) len,
- drv->socket_dir);
+ " test_dir=%p)",
+ __func__, drv->test_socket,
+ (unsigned long) data_len,
+ drv->test_dir);
return -1;
}
- dest = buf;
- dest += 4;
- broadcast = memcmp(dest, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0;
+ dest = data + 4;
+ broadcast = os_memcmp(dest, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0;
+
+#ifdef HOSTAPD
snprintf(desttxt, sizeof(desttxt), MACSTR, MAC2STR(dest));
+#endif /* HOSTAPD */
io[0].iov_base = "MLME ";
io[0].iov_len = 5;
- io[1].iov_base = (void *) buf;
- io[1].iov_len = len;
+ io[1].iov_base = (void *) data;
+ io[1].iov_len = data_len;
- memset(&msg, 0, sizeof(msg));
+ os_memset(&msg, 0, sizeof(msg));
msg.msg_iov = io;
msg.msg_iovlen = 2;
- dir = opendir(drv->socket_dir);
+#ifdef HOSTAPD
+ if (drv->test_dir == NULL) {
+ wpa_printf(MSG_DEBUG, "%s: test_dir == NULL", __func__);
+ return -1;
+ }
+
+ dir = opendir(drv->test_dir);
if (dir == NULL) {
perror("test_driver: opendir");
return -1;
if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
continue;
#endif /* _DIRENT_HAVE_D_TYPE */
- if (strcmp(dent->d_name, ".") == 0 ||
- strcmp(dent->d_name, "..") == 0)
+ if (os_strcmp(dent->d_name, ".") == 0 ||
+ os_strcmp(dent->d_name, "..") == 0)
continue;
- memset(&addr, 0, sizeof(addr));
+ os_memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
- snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s",
- drv->socket_dir, dent->d_name);
+ os_snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s",
+ drv->test_dir, dent->d_name);
- if (strcmp(addr.sun_path, drv->own_socket_path) == 0)
+ if (os_strcmp(addr.sun_path, drv->own_socket_path) == 0)
continue;
- if (!broadcast && strstr(dent->d_name, desttxt) == NULL)
+ if (!broadcast && os_strstr(dent->d_name, desttxt) == NULL)
continue;
wpa_printf(MSG_DEBUG, "%s: Send management frame to %s",
msg.msg_namelen = sizeof(addr);
ret = sendmsg(drv->test_socket, &msg, 0);
if (ret < 0)
- perror("driver_test: sendmsg");
+ perror("driver_test: sendmsg(test_socket)");
}
closedir(dir);
+#else /* HOSTAPD */
+
+ if (os_memcmp(dest, drv->bssid, ETH_ALEN) == 0 ||
+ drv->test_dir == NULL) {
+ if (drv->hostapd_addr_udp_set) {
+ msg.msg_name = &drv->hostapd_addr_udp;
+ msg.msg_namelen = sizeof(drv->hostapd_addr_udp);
+ } else {
+#ifdef DRIVER_TEST_UNIX
+ msg.msg_name = &drv->hostapd_addr;
+ msg.msg_namelen = sizeof(drv->hostapd_addr);
+#endif /* DRIVER_TEST_UNIX */
+ }
+ } else if (broadcast) {
+ dir = opendir(drv->test_dir);
+ if (dir == NULL)
+ return -1;
+ while ((dent = readdir(dir))) {
+#ifdef _DIRENT_HAVE_D_TYPE
+ /* Skip the file if it is not a socket.
+ * Also accept DT_UNKNOWN (0) in case
+ * the C library or underlying file
+ * system does not support d_type. */
+ if (dent->d_type != DT_SOCK &&
+ dent->d_type != DT_UNKNOWN)
+ continue;
+#endif /* _DIRENT_HAVE_D_TYPE */
+ if (os_strcmp(dent->d_name, ".") == 0 ||
+ os_strcmp(dent->d_name, "..") == 0)
+ continue;
+ wpa_printf(MSG_DEBUG, "%s: Send broadcast MLME to %s",
+ __func__, dent->d_name);
+ os_memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ os_snprintf(addr.sun_path, sizeof(addr.sun_path),
+ "%s/%s", drv->test_dir, dent->d_name);
+
+ msg.msg_name = &addr;
+ msg.msg_namelen = sizeof(addr);
+
+ ret = sendmsg(drv->test_socket, &msg, 0);
+ if (ret < 0)
+ perror("driver_test: sendmsg(test_socket)");
+ }
+ closedir(dir);
+ return ret;
+ } else {
+ struct stat st;
+ os_memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ os_snprintf(addr.sun_path, sizeof(addr.sun_path),
+ "%s/AP-" MACSTR, drv->test_dir, MAC2STR(dest));
+ if (stat(addr.sun_path, &st) < 0) {
+ os_snprintf(addr.sun_path, sizeof(addr.sun_path),
+ "%s/STA-" MACSTR,
+ drv->test_dir, MAC2STR(dest));
+ }
+ msg.msg_name = &addr;
+ msg.msg_namelen = sizeof(addr);
+ }
+
+ if (sendmsg(drv->test_socket, &msg, 0) < 0) {
+ perror("sendmsg(test_socket)");
+ return -1;
+ }
+#endif /* HOSTAPD */
- hdr = (struct ieee80211_hdr *) buf;
+ hdr = (struct ieee80211_hdr *) data;
fc = le_to_host16(hdr->frame_control);
- hostapd_mgmt_tx_cb(drv->hapd, (u8 *) buf, len, WLAN_FC_GET_STYPE(fc),
- ret >= 0);
+#ifdef HOSTAPD
+ hostapd_mgmt_tx_cb(drv->hapd, (u8 *) data, data_len,
+ WLAN_FC_GET_STYPE(fc), ret >= 0);
+#else /* HOSTAPD */
+ if (drv->ap) {
+ ap_mgmt_tx_cb(drv->ctx, (u8 *) data, data_len,
+ WLAN_FC_GET_STYPE(fc), ret >= 0);
+ }
+#endif /* HOSTAPD */
return ret;
}
-static void test_driver_scan(struct test_driver_data *drv,
+static void test_driver_scan(struct wpa_driver_test_data *drv,
struct sockaddr_un *from, socklen_t fromlen,
char *data)
{
MAC2STR(sa));
wpa_hexdump(MSG_MSGDUMP, "test_driver: scan IEs", ie, ielen);
- hostapd_wps_probe_req_rx(drv->hapd, sa, ie, ielen);
+#ifdef HOSTAPD
+ hostapd_probe_req_rx(drv->hapd, sa, ie, ielen);
+#endif /* HOSTAPD */
}
for (bss = drv->bss; bss; bss = bss->next) {
}
-static struct hostapd_data * test_driver_get_hapd(struct test_driver_data *drv,
- struct test_driver_bss *bss)
+static struct hostapd_data *
+test_driver_get_hapd(struct wpa_driver_test_data *drv,
+ struct test_driver_bss *bss)
{
+#ifdef HOSTAPD
struct hostapd_iface *iface = drv->hapd->iface;
struct hostapd_data *hapd = NULL;
size_t i;
}
return hapd;
+#else /* HOSTAPD */
+ return NULL;
+#endif /* HOSTAPD */
}
-static int test_driver_new_sta(struct test_driver_data *drv,
+static int test_driver_new_sta(struct wpa_driver_test_data *drv,
struct test_driver_bss *bss, const u8 *addr,
const u8 *ie, size_t ielen)
{
if (hapd == NULL)
return -1;
+#ifdef HOSTAPD
return hostapd_notif_assoc(hapd, addr, ie, ielen);
+#else /* HOSTAPD */
+ return -1;
+#endif /* HOSTAPD */
}
-static void test_driver_assoc(struct test_driver_data *drv,
+static void test_driver_assoc(struct wpa_driver_test_data *drv,
struct sockaddr_un *from, socklen_t fromlen,
char *data)
{
}
-static void test_driver_disassoc(struct test_driver_data *drv,
+static void test_driver_disassoc(struct wpa_driver_test_data *drv,
struct sockaddr_un *from, socklen_t fromlen)
{
struct test_client_socket *cli;
if (!cli)
return;
+#ifdef HOSTAPD
hostapd_notif_disassoc(drv->hapd, cli->addr);
+#endif /* HOSTAPD */
}
-static void test_driver_eapol(struct test_driver_data *drv,
+static void test_driver_eapol(struct wpa_driver_test_data *drv,
struct sockaddr_un *from, socklen_t fromlen,
u8 *data, size_t datalen)
{
+#ifdef HOSTAPD
struct test_client_socket *cli;
+#endif /* HOSTAPD */
+ const u8 *src = NULL;
+
if (datalen > 14) {
/* Skip Ethernet header */
+ src = data + ETH_ALEN;
wpa_printf(MSG_DEBUG, "test_driver: dst=" MACSTR " src="
MACSTR " proto=%04x",
- MAC2STR(data), MAC2STR(data + ETH_ALEN),
+ MAC2STR(data), MAC2STR(src),
WPA_GET_BE16(data + 2 * ETH_ALEN));
data += 14;
datalen -= 14;
}
+#ifdef HOSTAPD
cli = test_driver_get_cli(drv, from, fromlen);
if (cli) {
struct hostapd_data *hapd;
wpa_printf(MSG_DEBUG, "test_socket: EAPOL from unknown "
"client");
}
+#else /* HOSTAPD */
+ if (src)
+ wpa_supplicant_rx_eapol(drv->ctx, src, data, datalen);
+#endif /* HOSTAPD */
}
-static void test_driver_ether(struct test_driver_data *drv,
+static void test_driver_ether(struct wpa_driver_test_data *drv,
struct sockaddr_un *from, socklen_t fromlen,
u8 *data, size_t datalen)
{
#ifdef CONFIG_IEEE80211R
if (be_to_host16(eth->h_proto) == ETH_P_RRB) {
+#ifdef HOSTAPD
wpa_ft_rrb_rx(drv->hapd->wpa_auth, eth->h_source,
data + sizeof(*eth), datalen - sizeof(*eth));
+#endif /* HOSTAPD */
}
#endif /* CONFIG_IEEE80211R */
}
-static void test_driver_mlme(struct test_driver_data *drv,
+static void test_driver_mlme(struct wpa_driver_test_data *drv,
struct sockaddr_un *from, socklen_t fromlen,
u8 *data, size_t datalen)
{
__func__);
return;
}
+#ifdef HOSTAPD
hostapd_mgmt_rx(drv->hapd, data, datalen, WLAN_FC_GET_STYPE(fc), NULL);
+#else /* HOSTAPD */
+ ap_mgmt_rx(drv->ctx, data, datalen, WLAN_FC_GET_STYPE(fc), NULL);
+#endif /* HOSTAPD */
}
static void test_driver_receive_unix(int sock, void *eloop_ctx, void *sock_ctx)
{
- struct test_driver_data *drv = eloop_ctx;
+ struct wpa_driver_test_data *drv = eloop_ctx;
char buf[2000];
int res;
struct sockaddr_un from;
static struct test_driver_bss *
-test_driver_get_bss(struct test_driver_data *drv, const char *ifname)
+test_driver_get_bss(struct wpa_driver_test_data *drv, const char *ifname)
{
struct test_driver_bss *bss;
static int test_driver_set_generic_elem(const char *ifname, void *priv,
const u8 *elem, size_t elem_len)
{
- struct test_driver_data *drv = priv;
+ struct wpa_driver_test_data *drv = priv;
struct test_driver_bss *bss;
bss = test_driver_get_bss(drv, ifname);
static int test_driver_set_wps_beacon_ie(const char *ifname, void *priv,
const u8 *ie, size_t len)
{
- struct test_driver_data *drv = priv;
+ struct wpa_driver_test_data *drv = priv;
struct test_driver_bss *bss;
wpa_hexdump(MSG_DEBUG, "test_driver: Beacon WPS IE", ie, len);
static int test_driver_set_wps_probe_resp_ie(const char *ifname, void *priv,
const u8 *ie, size_t len)
{
- struct test_driver_data *drv = priv;
+ struct wpa_driver_test_data *drv = priv;
struct test_driver_bss *bss;
wpa_hexdump(MSG_DEBUG, "test_driver: ProbeResp WPS IE", ie, len);
}
-static int test_driver_sta_deauth(void *priv, const u8 *addr, int reason)
+static int test_driver_sta_deauth(void *priv, const u8 *own_addr,
+ const u8 *addr, int reason)
{
- struct test_driver_data *drv = priv;
+ struct wpa_driver_test_data *drv = priv;
struct test_client_socket *cli;
if (drv->test_socket < 0)
}
-static int test_driver_sta_disassoc(void *priv, const u8 *addr, int reason)
+static int test_driver_sta_disassoc(void *priv, const u8 *own_addr,
+ const u8 *addr, int reason)
{
- struct test_driver_data *drv = priv;
+ struct wpa_driver_test_data *drv = priv;
struct test_client_socket *cli;
if (drv->test_socket < 0)
static int test_driver_bss_add(void *priv, const char *ifname, const u8 *bssid)
{
- struct test_driver_data *drv = priv;
+ struct wpa_driver_test_data *drv = priv;
struct test_driver_bss *bss;
wpa_printf(MSG_DEBUG, "%s(ifname=%s bssid=" MACSTR ")",
static int test_driver_bss_remove(void *priv, const char *ifname)
{
- struct test_driver_data *drv = priv;
+ struct wpa_driver_test_data *drv = priv;
struct test_driver_bss *bss, *prev;
struct test_client_socket *cli, *prev_c;
static int test_driver_set_ssid(const char *ifname, void *priv, const u8 *buf,
int len)
{
- struct test_driver_data *drv = priv;
+ struct wpa_driver_test_data *drv = priv;
struct test_driver_bss *bss;
wpa_printf(MSG_DEBUG, "%s(ifname=%s)", __func__, ifname);
static int test_driver_set_privacy(const char *ifname, void *priv, int enabled)
{
- struct test_driver_data *drv = priv;
+ struct wpa_driver_test_data *drv = priv;
struct test_driver_bss *bss;
wpa_printf(MSG_DEBUG, "%s(ifname=%s enabled=%d)",
}
-static int test_driver_set_key(const char *iface, void *priv, wpa_alg alg,
- const u8 *addr, int key_idx, int set_tx,
- const u8 *seq, size_t seq_len,
- const u8 *key, size_t key_len)
-{
- wpa_printf(MSG_DEBUG, "%s(iface=%s alg=%d idx=%d set_tx=%d)",
- __func__, iface, alg, key_idx, set_tx);
- if (addr)
- wpa_printf(MSG_DEBUG, " addr=" MACSTR, MAC2STR(addr));
- if (key)
- wpa_hexdump_key(MSG_DEBUG, " key", key, key_len);
- return 0;
-}
-
-
static int test_driver_set_sta_vlan(void *priv, const u8 *addr,
const char *ifname, int vlan_id)
{
static int test_driver_sta_add(const char *ifname, void *priv,
struct hostapd_sta_add_params *params)
{
- struct test_driver_data *drv = priv;
+ struct wpa_driver_test_data *drv = priv;
struct test_client_socket *cli;
struct test_driver_bss *bss;
}
-static void * test_driver_init(struct hostapd_data *hapd)
+static void * test_driver_init(struct hostapd_data *hapd,
+ struct wpa_init_params *params)
{
- struct test_driver_data *drv;
+ struct wpa_driver_test_data *drv;
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 wpa_driver_test_data));
if (drv == NULL) {
printf("Could not allocate memory for test driver data\n");
return NULL;
}
+ drv->ap = 1;
drv->bss = os_zalloc(sizeof(*drv->bss));
if (drv->bss == NULL) {
printf("Could not allocate memory for test driver BSS data\n");
drv->hapd = hapd;
/* Generate a MAC address to help testing with multiple APs */
- hapd->own_addr[0] = 0x02; /* locally administered */
- sha1_prf((const u8 *) hapd->conf->iface, strlen(hapd->conf->iface),
+ params->own_addr[0] = 0x02; /* locally administered */
+ sha1_prf((const u8 *) params->ifname, strlen(params->ifname),
"hostapd test bssid generation",
- (const u8 *) hapd->conf->ssid.ssid, hapd->conf->ssid.ssid_len,
- hapd->own_addr + 1, ETH_ALEN - 1);
+ params->ssid, params->ssid_len,
+ params->own_addr + 1, ETH_ALEN - 1);
- os_strlcpy(drv->bss->ifname, hapd->conf->iface, IFNAMSIZ);
- memcpy(drv->bss->bssid, hapd->own_addr, ETH_ALEN);
+ os_strlcpy(drv->bss->ifname, params->ifname, IFNAMSIZ);
+ memcpy(drv->bss->bssid, params->own_addr, ETH_ALEN);
- if (hapd->conf->test_socket) {
- if (strlen(hapd->conf->test_socket) >=
+ if (params->test_socket) {
+ if (os_strlen(params->test_socket) >=
sizeof(addr_un.sun_path)) {
printf("Too long test_socket path\n");
- test_driver_free_priv(drv);
+ wpa_driver_test_deinit(drv);
return NULL;
}
- if (strncmp(hapd->conf->test_socket, "DIR:", 4) == 0) {
- size_t len = strlen(hapd->conf->test_socket) + 30;
- drv->socket_dir = strdup(hapd->conf->test_socket + 4);
+ if (strncmp(params->test_socket, "DIR:", 4) == 0) {
+ size_t len = strlen(params->test_socket) + 30;
+ drv->test_dir = strdup(params->test_socket + 4);
drv->own_socket_path = malloc(len);
if (drv->own_socket_path) {
snprintf(drv->own_socket_path, len,
"%s/AP-" MACSTR,
- hapd->conf->test_socket + 4,
- MAC2STR(hapd->own_addr));
+ params->test_socket + 4,
+ MAC2STR(params->own_addr));
}
- } else if (strncmp(hapd->conf->test_socket, "UDP:", 4) == 0) {
- drv->udp_port = atoi(hapd->conf->test_socket + 4);
+ } else if (strncmp(params->test_socket, "UDP:", 4) == 0) {
+ drv->udp_port = atoi(params->test_socket + 4);
} else {
- drv->own_socket_path = strdup(hapd->conf->test_socket);
+ drv->own_socket_path = strdup(params->test_socket);
}
if (drv->own_socket_path == NULL && drv->udp_port == 0) {
- test_driver_free_priv(drv);
+ wpa_driver_test_deinit(drv);
return NULL;
}
SOCK_DGRAM, 0);
if (drv->test_socket < 0) {
perror("socket");
- test_driver_free_priv(drv);
+ wpa_driver_test_deinit(drv);
return NULL;
}
close(drv->test_socket);
if (drv->own_socket_path)
unlink(drv->own_socket_path);
- test_driver_free_priv(drv);
+ wpa_driver_test_deinit(drv);
return NULL;
}
eloop_register_read_sock(drv->test_socket,
}
-static void test_driver_deinit(void *priv)
-{
- struct test_driver_data *drv = priv;
- struct test_client_socket *cli, *prev;
-
- cli = drv->cli;
- while (cli) {
- prev = cli;
- cli = cli->next;
- free(prev);
- }
-
- if (drv->test_socket >= 0) {
- eloop_unregister_read_sock(drv->test_socket);
- close(drv->test_socket);
- if (drv->own_socket_path)
- unlink(drv->own_socket_path);
- }
-
- /* There should be only one BSS remaining at this point. */
- if (drv->bss == NULL)
- wpa_printf(MSG_ERROR, "%s: drv->bss == NULL", __func__);
- else if (drv->bss->next)
- wpa_printf(MSG_ERROR, "%s: drv->bss->next != NULL", __func__);
-
- test_driver_free_priv(drv);
-}
-
-#else /* HOSTAPD */
-
static void wpa_driver_test_poll(void *eloop_ctx, void *timeout_ctx)
{
struct wpa_driver_test_data *drv = eloop_ctx;
}
-static int wpa_driver_test_set_wpa(void *priv, int enabled)
-{
- wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
- return 0;
-}
-
-
static void wpa_driver_test_scan_timeout(void *eloop_ctx, void *timeout_ctx)
{
wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
size_t i;
wpa_printf(MSG_DEBUG, "%s: priv=%p", __func__, priv);
+
+ os_free(drv->probe_req_ie);
+ if (params->extra_ies) {
+ drv->probe_req_ie = os_malloc(params->extra_ies_len);
+ if (drv->probe_req_ie == NULL) {
+ drv->probe_req_ie_len = 0;
+ return -1;
+ }
+ os_memcpy(drv->probe_req_ie, params->extra_ies,
+ params->extra_ies_len);
+ drv->probe_req_ie_len = params->extra_ies_len;
+ } else {
+ drv->probe_req_ie = NULL;
+ drv->probe_req_ie_len = 0;
+ }
+
for (i = 0; i < params->num_ssids; i++)
wpa_hexdump(MSG_DEBUG, "Scan SSID",
params->ssids[i].ssid, params->ssids[i].ssid_len);
}
-static int wpa_driver_test_set_key(void *priv, wpa_alg alg, const u8 *addr,
- int key_idx, int set_tx,
+static int wpa_driver_test_set_key(const char *ifname, void *priv, wpa_alg alg,
+ const u8 *addr, int key_idx, int set_tx,
const u8 *seq, size_t seq_len,
const u8 *key, size_t key_len)
{
- wpa_printf(MSG_DEBUG, "%s: priv=%p alg=%d key_idx=%d set_tx=%d",
- __func__, priv, alg, key_idx, set_tx);
- if (addr) {
+ wpa_printf(MSG_DEBUG, "%s: ifname=%s priv=%p alg=%d key_idx=%d "
+ "set_tx=%d",
+ __func__, ifname, priv, alg, key_idx, set_tx);
+ if (addr)
wpa_printf(MSG_DEBUG, " addr=" MACSTR, MAC2STR(addr));
- }
- if (seq) {
+ if (seq)
wpa_hexdump(MSG_DEBUG, " seq", seq, seq_len);
+ if (key)
+ wpa_hexdump_key(MSG_DEBUG, " key", key, key_len);
+ return 0;
+}
+
+
+static int wpa_driver_update_mode(struct wpa_driver_test_data *drv, int ap)
+{
+ if (ap && !drv->ap) {
+ wpa_driver_test_close_test_socket(drv);
+ wpa_driver_test_attach(drv, drv->test_dir, 1);
+ drv->ap = 1;
+ } else if (!ap && drv->ap) {
+ wpa_driver_test_close_test_socket(drv);
+ wpa_driver_test_attach(drv, drv->test_dir, 0);
+ drv->ap = 0;
}
- if (key) {
- wpa_hexdump(MSG_DEBUG, " key", key, key_len);
- }
+
return 0;
}
} else
drv->assoc_wpa_ie_len = 0;
+ wpa_driver_update_mode(drv, params->mode == IEEE80211_MODE_AP);
+
drv->ibss = params->mode == IEEE80211_MODE_IBSS;
drv->privacy = params->key_mgmt_suite &
(WPA_KEY_MGMT_IEEE8021X |
}
#endif /* DRIVER_TEST_UNIX */
- if (drv->test_socket >= 0 &&
- (drv->hostapd_addr_set || drv->hostapd_addr_udp_set)) {
+ if (params->mode == IEEE80211_MODE_AP) {
+ struct test_driver_bss *bss;
+ os_memcpy(drv->ssid, params->ssid, params->ssid_len);
+ drv->ssid_len = params->ssid_len;
+
+ test_driver_free_bsses(drv);
+ bss = drv->bss = os_zalloc(sizeof(*drv->bss));
+ if (bss == NULL)
+ return -1;
+ os_memcpy(bss->bssid, drv->own_addr, ETH_ALEN);
+ os_memcpy(bss->ssid, params->ssid, params->ssid_len);
+ bss->ssid_len = params->ssid_len;
+ bss->privacy = drv->privacy;
+ if (params->wpa_ie && params->wpa_ie_len) {
+ bss->ie = os_malloc(params->wpa_ie_len);
+ if (bss->ie) {
+ os_memcpy(bss->ie, params->wpa_ie,
+ params->wpa_ie_len);
+ bss->ielen = params->wpa_ie_len;
+ }
+ }
+ } else 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);
data += 14;
data_len -= 14;
}
+#ifndef HOSTAPD
wpa_supplicant_rx_eapol(drv->ctx, src, data, data_len);
+#endif /* HOSTAPD */
}
socklen_t fromlen = sizeof(from);
const size_t buflen = 2000;
+ if (drv->ap) {
+ test_driver_receive_unix(sock, eloop_ctx, sock_ctx);
+ return;
+ }
+
buf = os_malloc(buflen);
if (buf == NULL)
return;
static void wpa_driver_test_deinit(void *priv)
{
struct wpa_driver_test_data *drv = priv;
+ struct test_client_socket *cli, *prev;
int i;
+
+ cli = drv->cli;
+ while (cli) {
+ prev = cli;
+ cli = cli->next;
+ os_free(prev);
+ }
+
+#ifdef HOSTAPD
+ /* There should be only one BSS remaining at this point. */
+ if (drv->bss == NULL)
+ wpa_printf(MSG_ERROR, "%s: drv->bss == NULL", __func__);
+ else if (drv->bss->next)
+ wpa_printf(MSG_ERROR, "%s: drv->bss->next != NULL", __func__);
+#endif /* HOSTAPD */
+
+ test_driver_free_bsses(drv);
+
wpa_driver_test_close_test_socket(drv);
eloop_cancel_timeout(wpa_driver_test_scan_timeout, drv, drv->ctx);
eloop_cancel_timeout(wpa_driver_test_poll, drv, NULL);
static int wpa_driver_test_attach(struct wpa_driver_test_data *drv,
- const char *dir)
+ const char *dir, int ap)
{
#ifdef DRIVER_TEST_UNIX
static unsigned int counter = 0;
drv->own_socket_path = os_malloc(len);
if (drv->own_socket_path == NULL)
return -1;
- os_snprintf(drv->own_socket_path, len, "%s/STA-" MACSTR,
- dir, MAC2STR(drv->own_addr));
+ os_snprintf(drv->own_socket_path, len, "%s/%s-" MACSTR,
+ dir, ap ? "AP" : "STA", MAC2STR(drv->own_addr));
} else {
drv->own_socket_path = os_malloc(100);
if (drv->own_socket_path == NULL)
end = os_strchr(drv->test_dir, ' ');
if (end)
*end = '\0';
- if (wpa_driver_test_attach(drv, drv->test_dir))
+ if (wpa_driver_test_attach(drv, drv->test_dir, 0))
return -1;
} else {
pos = os_strstr(param, "test_udp=");
if (wpa_driver_test_attach_udp(drv, dst))
return -1;
os_free(dst);
- } else if (wpa_driver_test_attach(drv, NULL))
+ } else if (wpa_driver_test_attach(drv, NULL, 0))
return -1;
}
WPA_DRIVER_AUTH_LEAP;
if (drv->use_mlme)
capa->flags |= WPA_DRIVER_FLAGS_USER_SPACE_MLME;
+ capa->flags |= WPA_DRIVER_FLAGS_AP;
capa->max_scan_ssids = 2;
return 0;
}
-#ifdef CONFIG_CLIENT_MLME
static int wpa_driver_test_set_channel(void *priv, hostapd_hw_mode phymode,
int chan, int freq)
{
}
-static int wpa_driver_test_send_mlme(void *priv, const u8 *data,
- size_t data_len)
-{
- struct wpa_driver_test_data *drv = priv;
- struct msghdr msg;
- struct iovec io[2];
- struct sockaddr_un addr;
- const u8 *dest;
- struct dirent *dent;
- DIR *dir;
-
- wpa_hexdump(MSG_MSGDUMP, "test_send_mlme", data, data_len);
- if (data_len < 10)
- return -1;
- dest = data + 4;
-
- io[0].iov_base = "MLME ";
- io[0].iov_len = 5;
- io[1].iov_base = (u8 *) data;
- io[1].iov_len = data_len;
-
- os_memset(&msg, 0, sizeof(msg));
- msg.msg_iov = io;
- msg.msg_iovlen = 2;
- if (os_memcmp(dest, drv->bssid, ETH_ALEN) == 0 ||
- drv->test_dir == NULL) {
- if (drv->hostapd_addr_udp_set) {
- msg.msg_name = &drv->hostapd_addr_udp;
- msg.msg_namelen = sizeof(drv->hostapd_addr_udp);
- } else {
-#ifdef DRIVER_TEST_UNIX
- msg.msg_name = &drv->hostapd_addr;
- msg.msg_namelen = sizeof(drv->hostapd_addr);
-#endif /* DRIVER_TEST_UNIX */
- }
- } else if (os_memcmp(dest, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0)
- {
- dir = opendir(drv->test_dir);
- if (dir == NULL)
- return -1;
- while ((dent = readdir(dir))) {
-#ifdef _DIRENT_HAVE_D_TYPE
- /* Skip the file if it is not a socket.
- * Also accept DT_UNKNOWN (0) in case
- * the C library or underlying file
- * system does not support d_type. */
- if (dent->d_type != DT_SOCK &&
- dent->d_type != DT_UNKNOWN)
- continue;
-#endif /* _DIRENT_HAVE_D_TYPE */
- if (os_strcmp(dent->d_name, ".") == 0 ||
- os_strcmp(dent->d_name, "..") == 0)
- continue;
- wpa_printf(MSG_DEBUG, "%s: Send broadcast MLME to %s",
- __func__, dent->d_name);
- os_memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- os_snprintf(addr.sun_path, sizeof(addr.sun_path),
- "%s/%s", drv->test_dir, dent->d_name);
-
- msg.msg_name = &addr;
- msg.msg_namelen = sizeof(addr);
-
- if (sendmsg(drv->test_socket, &msg, 0) < 0)
- perror("sendmsg(test_socket)");
- }
- closedir(dir);
- return 0;
- } else {
- struct stat st;
- os_memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- os_snprintf(addr.sun_path, sizeof(addr.sun_path),
- "%s/AP-" MACSTR, drv->test_dir, MAC2STR(dest));
- if (stat(addr.sun_path, &st) < 0) {
- os_snprintf(addr.sun_path, sizeof(addr.sun_path),
- "%s/STA-" MACSTR,
- drv->test_dir, MAC2STR(dest));
- }
- msg.msg_name = &addr;
- msg.msg_namelen = sizeof(addr);
- }
-
- if (sendmsg(drv->test_socket, &msg, 0) < 0) {
- perror("sendmsg(test_socket)");
- return -1;
- }
-
- return 0;
-}
-
-
static int wpa_driver_test_mlme_add_sta(void *priv, const u8 *addr,
const u8 *supp_rates,
size_t supp_rates_len)
wpa_printf(MSG_DEBUG, "%s: bssid=" MACSTR, __func__, MAC2STR(bssid));
return 0;
}
-#endif /* CONFIG_CLIENT_MLME */
-
-
-static int wpa_driver_test_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;
-}
static void * wpa_driver_test_global_init(void)
return iface;
}
-#endif /* HOSTAPD */
-
-#if defined(HOSTAPD) || defined(CONFIG_CLIENT_MLME)
static struct hostapd_hw_modes *
wpa_driver_test_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
{
}
return NULL;
}
-#endif /* HOSTAPD || CONFIG_CLIENT_MLME */
const struct wpa_driver_ops wpa_driver_test_ops = {
"test",
"wpa_supplicant test driver",
-#ifdef HOSTAPD
.hapd_init = test_driver_init,
- .hapd_deinit = test_driver_deinit,
+ .hapd_deinit = wpa_driver_test_deinit,
.hapd_send_eapol = test_driver_send_eapol,
- .send_mgmt_frame = test_driver_send_mgmt_frame,
+ .send_mlme = wpa_driver_test_send_mlme,
.set_generic_elem = test_driver_set_generic_elem,
.sta_deauth = test_driver_sta_deauth,
.sta_disassoc = test_driver_sta_disassoc,
.valid_bss_mask = test_driver_valid_bss_mask,
.hapd_set_ssid = test_driver_set_ssid,
.set_privacy = test_driver_set_privacy,
- .hapd_set_key = test_driver_set_key,
.set_sta_vlan = test_driver_set_sta_vlan,
.sta_add = test_driver_sta_add,
.send_ether = test_driver_send_ether,
.set_wps_beacon_ie = test_driver_set_wps_beacon_ie,
.set_wps_probe_resp_ie = test_driver_set_wps_probe_resp_ie,
-#else /* HOSTAPD */
- wpa_driver_test_get_bssid,
- wpa_driver_test_get_ssid,
- wpa_driver_test_set_wpa,
- wpa_driver_test_set_key,
- NULL /* init */,
- wpa_driver_test_deinit,
- wpa_driver_test_set_param,
- NULL /* set_countermeasures */,
- NULL /* set_drop_unencrypted */,
- NULL /* scan */,
- NULL /* get_scan_results */,
- wpa_driver_test_deauthenticate,
- wpa_driver_test_disassociate,
- wpa_driver_test_associate,
- NULL /* set_auth_alg */,
- NULL /* add_pmkid */,
- NULL /* remove_pmkid */,
- NULL /* flush_pmkid */,
- wpa_driver_test_get_capa,
- NULL /* poll */,
- NULL /* get_ifname */,
- wpa_driver_test_get_mac_addr,
- wpa_driver_test_send_eapol,
- NULL /* set_operstate */,
- wpa_driver_test_mlme_setprotection,
-#ifdef CONFIG_CLIENT_MLME
- wpa_driver_test_get_hw_feature_data,
- wpa_driver_test_set_channel,
- wpa_driver_test_set_ssid,
- wpa_driver_test_set_bssid,
- wpa_driver_test_send_mlme,
- wpa_driver_test_mlme_add_sta,
- wpa_driver_test_mlme_remove_sta,
-#else /* CONFIG_CLIENT_MLME */
- NULL /* get_hw_feature_data */,
- NULL /* set_channel */,
- NULL /* set_ssid */,
- NULL /* set_bssid */,
- NULL /* send_mlme */,
- NULL /* mlme_add_sta */,
- NULL /* mlme_remove_sta */,
-#endif /* CONFIG_CLIENT_MLME */
- NULL /* update_ft_ies */,
- NULL /* send_ft_action */,
- wpa_driver_test_get_scan_results2,
- wpa_driver_test_set_probe_req_ie,
- NULL /* set_mode */,
- NULL /* set_country */,
- wpa_driver_test_global_init,
- wpa_driver_test_global_deinit,
- wpa_driver_test_init2,
- wpa_driver_test_get_interfaces,
- wpa_driver_test_scan,
- NULL /* authenticate */,
- NULL /* set_beacon */,
- NULL /* set_beacon_int */,
- NULL /* hapd_init */,
- NULL /* init_bssid */,
- NULL /* hapd_deinit */,
- NULL /* set_ieee8021x */,
- NULL /* set_privacy */,
- NULL /* hapd_set_key */,
- NULL /* get_seqnum */,
- NULL /* get_seqnum_igtk */,
- NULL /* flush */,
- NULL /* set_generic_elem */,
- NULL /* read_sta_data */,
- NULL /* hapd_send_eapol */,
- NULL /* sta_deauth */,
- NULL /* sta_disassoc */,
- NULL /* sta_remove */,
- NULL /* hapd_get_ssid */,
- NULL /* hapd_set_ssid */,
- NULL /* hapd_set_countermeasures */,
- NULL /* send_mgmt_frame */,
- NULL /* sta_add */,
- NULL /* get_inact_sec */,
- NULL /* sta_clear_stats */,
- NULL /* set_freq */,
- NULL /* set_rts */,
- NULL /* set_frag */,
- NULL /* set_retry */,
- NULL /* sta_set_flags */,
- NULL /* set_rate_sets */,
- NULL /* hapd_set_country */,
- NULL /* set_ieee80211d */,
- NULL /* hapd_set_beacon */,
- NULL /* set_internal_bridge */,
- NULL /* hapd_set_beacon_int */,
- NULL /* set_broadcast_ssid */,
- NULL /* set_cts_protect */,
- NULL /* set_preamble */,
- NULL /* set_short_slot_time */,
- NULL /* set_tx_queue_params */,
- NULL /* bss_add */,
- NULL /* bss_remove */,
- NULL /* valid_bss_mask */,
- NULL /* passive_scan */,
- NULL /* if_add */,
- NULL /* if_update */,
- NULL /* if_remove */,
- NULL /* set_sta_vlan */,
- NULL /* commit */,
- NULL /* send_ether */,
- NULL /* set_radius_acl_auth */,
- NULL /* set_radius_acl_expire */,
- NULL /* set_ht_params */,
- NULL /* set_wps_beacon_ie */,
- NULL /* set_wps_probe_resp_ie */,
- NULL /* get_neighbor_bss */
-#endif /* HOSTAPD */
+ .get_bssid = wpa_driver_test_get_bssid,
+ .get_ssid = wpa_driver_test_get_ssid,
+ .set_key = wpa_driver_test_set_key,
+ .deinit = wpa_driver_test_deinit,
+ .set_param = wpa_driver_test_set_param,
+ .deauthenticate = wpa_driver_test_deauthenticate,
+ .disassociate = wpa_driver_test_disassociate,
+ .associate = wpa_driver_test_associate,
+ .get_capa = wpa_driver_test_get_capa,
+ .get_mac_addr = wpa_driver_test_get_mac_addr,
+ .send_eapol = wpa_driver_test_send_eapol,
+ .mlme_setprotection = wpa_driver_test_mlme_setprotection,
+ .set_channel = wpa_driver_test_set_channel,
+ .set_ssid = wpa_driver_test_set_ssid,
+ .set_bssid = wpa_driver_test_set_bssid,
+ .mlme_add_sta = wpa_driver_test_mlme_add_sta,
+ .mlme_remove_sta = wpa_driver_test_mlme_remove_sta,
+ .get_scan_results2 = wpa_driver_test_get_scan_results2,
+ .global_init = wpa_driver_test_global_init,
+ .global_deinit = wpa_driver_test_global_deinit,
+ .init2 = wpa_driver_test_init2,
+ .get_interfaces = wpa_driver_test_get_interfaces,
+ .scan2 = wpa_driver_test_scan,
};