#include <dirent.h>
#include "hostapd.h"
+#include "config.h"
#include "driver.h"
#include "sha1.h"
#include "eloop.h"
-#include "ieee802_1x.h"
-#include "sta_info.h"
#include "wpa.h"
-#include "accounting.h"
-#include "radius/radius.h"
#include "l2_packet/l2_packet.h"
-#include "ieee802_11.h"
#include "hw_features.h"
+#include "wps_hostapd.h"
+#include "ieee802_11_defs.h"
struct test_client_socket {
u8 bssid[ETH_ALEN];
u8 *ie;
size_t ielen;
+ u8 *wps_beacon_ie;
+ size_t wps_beacon_ie_len;
+ u8 *wps_probe_resp_ie;
+ size_t wps_probe_resp_ie_len;
u8 ssid[32];
size_t ssid_len;
int privacy;
struct test_driver_bss *bss;
char *socket_dir;
char *own_socket_path;
+ int udp_port;
};
static void test_driver_free_bss(struct test_driver_bss *bss)
{
free(bss->ie);
+ free(bss->wps_beacon_ie);
+ free(bss->wps_probe_resp_ie);
free(bss);
}
memcpy(eth.h_dest, addr, ETH_ALEN);
memcpy(eth.h_source, own_addr, ETH_ALEN);
- eth.h_proto = htons(ETH_P_EAPOL);
+ eth.h_proto = host_to_be16(ETH_P_EAPOL);
io[0].iov_base = "EAPOL ";
io[0].iov_len = 6;
memcpy(eth.h_dest, dst, ETH_ALEN);
memcpy(eth.h_source, src, ETH_ALEN);
- eth.h_proto = htons(proto);
+ eth.h_proto = host_to_be16(proto);
io[0].iov_base = "ETHER ";
io[0].iov_len = 6;
hdr = (struct ieee80211_hdr *) buf;
fc = le_to_host16(hdr->frame_control);
- ieee802_11_mgmt_cb(drv->hapd, (u8 *) buf, len, WLAN_FC_GET_STYPE(fc),
+ hostapd_mgmt_tx_cb(drv->hapd, (u8 *) buf, len, WLAN_FC_GET_STYPE(fc),
ret >= 0);
return ret;
static void test_driver_scan(struct test_driver_data *drv,
- struct sockaddr_un *from, socklen_t fromlen)
+ struct sockaddr_un *from, socklen_t fromlen,
+ char *data)
{
char buf[512], *pos, *end;
int ret;
struct test_driver_bss *bss;
+ u8 sa[ETH_ALEN];
+ u8 ie[512];
+ size_t ielen;
+
+ /* data: optional [ ' ' | STA-addr | ' ' | IEs(hex) ] */
wpa_printf(MSG_DEBUG, "test_driver: SCAN");
+ if (*data) {
+ if (*data != ' ' ||
+ hwaddr_aton(data + 1, sa)) {
+ wpa_printf(MSG_DEBUG, "test_driver: Unexpected SCAN "
+ "command format");
+ return;
+ }
+
+ data += 18;
+ while (*data == ' ')
+ data++;
+ ielen = os_strlen(data) / 2;
+ if (ielen > sizeof(ie))
+ ielen = sizeof(ie);
+ if (hexstr2bin(data, ie, ielen) < 0)
+ ielen = 0;
+
+ wpa_printf(MSG_DEBUG, "test_driver: Scan from " MACSTR,
+ MAC2STR(sa));
+ wpa_hexdump(MSG_MSGDUMP, "test_driver: scan IEs", ie, ielen);
+
+ hostapd_wps_probe_req_rx(drv->hapd, sa, ie, ielen);
+ }
+
for (bss = drv->bss; bss; bss = bss->next) {
pos = buf;
end = buf + sizeof(buf);
return;
pos += ret;
pos += wpa_snprintf_hex(pos, end - pos, bss->ie, bss->ielen);
+ pos += wpa_snprintf_hex(pos, end - pos, bss->wps_probe_resp_ie,
+ bss->wps_probe_resp_ie_len);
if (bss->privacy) {
ret = snprintf(pos, end - pos, " PRIVACY");
const u8 *ie, size_t ielen)
{
struct hostapd_data *hapd;
- struct sta_info *sta;
- int new_assoc, res;
hapd = test_driver_get_hapd(drv, bss);
if (hapd == NULL)
return -1;
- hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
- HOSTAPD_LEVEL_INFO, "associated");
-
- sta = ap_get_sta(hapd, addr);
- if (sta) {
- accounting_sta_stop(hapd, sta);
- } else {
- sta = ap_sta_add(hapd, addr);
- if (sta == NULL)
- return -1;
- }
- accounting_sta_get_id(hapd, sta);
-
- if (hapd->conf->wpa) {
- if (ie == NULL || ielen == 0) {
- printf("test_driver: no IE from STA\n");
- return -1;
- }
- if (sta->wpa_sm == NULL)
- sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
- sta->addr);
- if (sta->wpa_sm == NULL) {
- printf("test_driver: Failed to initialize WPA state "
- "machine\n");
- return -1;
- }
- res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
- ie, ielen, NULL, 0);
- if (res != WPA_IE_OK) {
- printf("WPA/RSN information element rejected? "
- "(res %u)\n", res);
- return -1;
- }
- }
-
- new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;
- sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
- wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
-
- hostapd_new_assoc_sta(hapd, sta, !new_assoc);
-
- ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
-
- return 0;
+ return hostapd_notif_assoc(hapd, addr, ie, ielen);
}
struct sockaddr_un *from, socklen_t fromlen)
{
struct test_client_socket *cli;
- struct sta_info *sta;
cli = test_driver_get_cli(drv, from, fromlen);
if (!cli)
return;
- hostapd_logger(drv->hapd, cli->addr, HOSTAPD_MODULE_IEEE80211,
- HOSTAPD_LEVEL_INFO, "disassociated");
-
- sta = ap_get_sta(drv->hapd, cli->addr);
- if (sta != NULL) {
- sta->flags &= ~WLAN_STA_ASSOC;
- wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
- sta->acct_terminate_cause =
- RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
- ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
- ap_free_sta(drv->hapd, sta);
- }
+ hostapd_notif_disassoc(drv->hapd, cli->addr);
}
{
struct test_client_socket *cli;
if (datalen > 14) {
- u8 *proto = data + 2 * ETH_ALEN;
/* Skip Ethernet header */
wpa_printf(MSG_DEBUG, "test_driver: dst=" MACSTR " src="
MACSTR " proto=%04x",
MAC2STR(data), MAC2STR(data + ETH_ALEN),
- WPA_GET_BE16(proto));
+ WPA_GET_BE16(data + 2 * ETH_ALEN));
data += 14;
datalen -= 14;
}
hapd = test_driver_get_hapd(drv, cli->bss);
if (hapd == NULL)
return;
- ieee802_1x_receive(hapd, cli->addr, data, datalen);
+ hostapd_eapol_receive(hapd, cli->addr, data, datalen);
} else {
wpa_printf(MSG_DEBUG, "test_socket: EAPOL from unknown "
"client");
__func__);
return;
}
- ieee802_11_mgmt(drv->hapd, data, datalen, WLAN_FC_GET_STYPE(fc), NULL);
+ hostapd_mgmt_rx(drv->hapd, data, datalen, WLAN_FC_GET_STYPE(fc), NULL);
}
wpa_printf(MSG_DEBUG, "test_driver: received %u bytes", res);
- if (strcmp(buf, "SCAN") == 0) {
- test_driver_scan(drv, &from, fromlen);
+ if (strncmp(buf, "SCAN", 4) == 0) {
+ test_driver_scan(drv, &from, fromlen, buf + 4);
} else if (strncmp(buf, "ASSOC ", 6) == 0) {
test_driver_assoc(drv, &from, fromlen, buf + 6);
} else if (strcmp(buf, "DISASSOC") == 0) {
}
+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 test_driver_bss *bss;
+
+ wpa_hexdump(MSG_DEBUG, "test_driver: Beacon WPS IE", ie, len);
+ bss = test_driver_get_bss(drv, ifname);
+ if (bss == NULL)
+ return -1;
+
+ free(bss->wps_beacon_ie);
+
+ if (ie == NULL) {
+ bss->wps_beacon_ie = NULL;
+ bss->wps_beacon_ie_len = 0;
+ return 0;
+ }
+
+ bss->wps_beacon_ie = malloc(len);
+ if (bss->wps_beacon_ie == NULL) {
+ bss->wps_beacon_ie_len = 0;
+ return -1;
+ }
+
+ memcpy(bss->wps_beacon_ie, ie, len);
+ bss->wps_beacon_ie_len = len;
+ return 0;
+}
+
+
+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 test_driver_bss *bss;
+
+ wpa_hexdump(MSG_DEBUG, "test_driver: ProbeResp WPS IE", ie, len);
+ bss = test_driver_get_bss(drv, ifname);
+ if (bss == NULL)
+ return -1;
+
+ free(bss->wps_probe_resp_ie);
+
+ if (ie == NULL) {
+ bss->wps_probe_resp_ie = NULL;
+ bss->wps_probe_resp_ie_len = 0;
+ return 0;
+ }
+
+ bss->wps_probe_resp_ie = malloc(len);
+ if (bss->wps_probe_resp_ie == NULL) {
+ bss->wps_probe_resp_ie_len = 0;
+ return -1;
+ }
+
+ memcpy(bss->wps_probe_resp_ie, ie, len);
+ bss->wps_probe_resp_ie_len = len;
+ return 0;
+}
+
+
static int test_driver_sta_deauth(void *priv, const u8 *addr, int reason)
{
struct test_driver_data *drv = priv;
}
modes[0].channels[0].chan = 1;
modes[0].channels[0].freq = 2412;
- modes[0].channels[0].flag = HOSTAPD_CHAN_W_SCAN |
- HOSTAPD_CHAN_W_ACTIVE_SCAN;
+ modes[0].channels[0].flag = 0;
modes[0].rates[0].rate = 10;
modes[0].rates[0].flags = HOSTAPD_RATE_BASIC | HOSTAPD_RATE_SUPPORTED |
HOSTAPD_RATE_CCK | HOSTAPD_RATE_MANDATORY;
}
modes[1].channels[0].chan = 1;
modes[1].channels[0].freq = 2412;
- modes[1].channels[0].flag = HOSTAPD_CHAN_W_SCAN |
- HOSTAPD_CHAN_W_ACTIVE_SCAN;
+ modes[1].channels[0].flag = 0;
modes[1].rates[0].rate = 10;
modes[1].rates[0].flags = HOSTAPD_RATE_BASIC | HOSTAPD_RATE_SUPPORTED |
HOSTAPD_RATE_CCK | HOSTAPD_RATE_MANDATORY;
}
modes[2].channels[0].chan = 60;
modes[2].channels[0].freq = 5300;
- modes[2].channels[0].flag = HOSTAPD_CHAN_W_SCAN |
- HOSTAPD_CHAN_W_ACTIVE_SCAN;
+ modes[2].channels[0].flag = 0;
modes[2].rates[0].rate = 60;
modes[2].rates[0].flags = HOSTAPD_RATE_BASIC | HOSTAPD_RATE_SUPPORTED |
HOSTAPD_RATE_MANDATORY;
}
-static int test_driver_set_encryption(const char *iface, void *priv,
- const char *alg, const u8 *addr, int idx,
- const u8 *key, size_t key_len, int txkey)
+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=%s idx=%d txkey=%d)",
- __func__, iface, alg, idx, txkey);
+ 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)
}
-static int test_driver_sta_add(const char *ifname, void *priv, const u8 *addr,
- u16 aid, u16 capability, u8 *supp_rates,
- size_t supp_rates_len, int flags,
- u16 listen_interval)
+static int test_driver_sta_add(const char *ifname, void *priv,
+ struct hostapd_sta_add_params *params)
{
struct test_driver_data *drv = priv;
struct test_client_socket *cli;
wpa_printf(MSG_DEBUG, "%s(ifname=%s addr=" MACSTR " aid=%d "
"capability=0x%x flags=0x%x listen_interval=%d)",
- __func__, ifname, MAC2STR(addr), aid, capability, flags,
- listen_interval);
+ __func__, ifname, MAC2STR(params->addr), params->aid,
+ params->capability, params->flags,
+ params->listen_interval);
wpa_hexdump(MSG_DEBUG, "test_driver_sta_add - supp_rates",
- supp_rates, supp_rates_len);
+ params->supp_rates, params->supp_rates_len);
cli = drv->cli;
while (cli) {
- if (memcmp(cli->addr, addr, ETH_ALEN) == 0)
+ if (os_memcmp(cli->addr, params->addr, ETH_ALEN) == 0)
break;
cli = cli->next;
}
static void * test_driver_init(struct hostapd_data *hapd)
{
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));
if (drv == NULL) {
memcpy(drv->bss->bssid, hapd->own_addr, ETH_ALEN);
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");
test_driver_free_priv(drv);
return NULL;
hapd->conf->test_socket + 4,
MAC2STR(hapd->own_addr));
}
+ } else if (strncmp(hapd->conf->test_socket, "UDP:", 4) == 0) {
+ drv->udp_port = atoi(hapd->conf->test_socket + 4);
} else {
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);
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) {
- perror("socket(PF_UNIX)");
+ perror("socket");
test_driver_free_priv(drv);
return NULL;
}
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- os_strlcpy(addr.sun_path, drv->own_socket_path,
- sizeof(addr.sun_path));
- if (bind(drv->test_socket, (struct sockaddr *) &addr,
- sizeof(addr)) < 0) {
+ if (drv->udp_port) {
+ os_memset(&addr_in, 0, sizeof(addr_in));
+ addr_in.sin_family = AF_INET;
+ addr_in.sin_port = htons(drv->udp_port);
+ addr = (struct sockaddr *) &addr_in;
+ 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)");
close(drv->test_socket);
- unlink(drv->own_socket_path);
+ if (drv->own_socket_path)
+ unlink(drv->own_socket_path);
test_driver_free_priv(drv);
return NULL;
}
if (drv->test_socket >= 0) {
eloop_unregister_read_sock(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. */
}
-const struct wpa_driver_ops wpa_driver_test_ops = {
+const struct hapd_driver_ops wpa_driver_test_ops = {
.name = "test",
.init = test_driver_init,
.deinit = test_driver_deinit,
.valid_bss_mask = test_driver_valid_bss_mask,
.set_ssid = test_driver_set_ssid,
.set_privacy = test_driver_set_privacy,
- .set_encryption = test_driver_set_encryption,
+ .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,
};