Fix couple of forgotten wpa_hw_modes -> hostapd_hw_modes
[wpasupplicant] / hostapd / driver_test.c
index e75614e..94da5d0 100644 (file)
 #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 {
@@ -44,6 +42,10 @@ struct test_driver_bss {
        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;
@@ -56,12 +58,15 @@ struct test_driver_data {
        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);
 }
 
@@ -131,7 +136,7 @@ static int test_driver_send_eapol(void *priv, const u8 *addr, const u8 *data,
 
        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;
@@ -174,7 +179,7 @@ static int test_driver_send_ether(void *priv, const u8 *dst, const u8 *src,
 
        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;
@@ -313,7 +318,7 @@ static int test_driver_send_mgmt_frame(void *priv, const void *buf,
 
        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;
@@ -321,14 +326,44 @@ static int test_driver_send_mgmt_frame(void *priv, const void *buf,
 
 
 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);
@@ -346,6 +381,8 @@ static void test_driver_scan(struct test_driver_data *drv,
                        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");
@@ -392,57 +429,12 @@ static int test_driver_new_sta(struct test_driver_data *drv,
                               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);
 }
 
 
@@ -527,24 +519,12 @@ static void test_driver_disassoc(struct test_driver_data *drv,
                                 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);
 }
 
 
@@ -554,12 +534,11 @@ static void test_driver_eapol(struct test_driver_data *drv,
 {
        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;
        }
@@ -569,7 +548,7 @@ static void test_driver_eapol(struct test_driver_data *drv,
                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");
@@ -632,7 +611,7 @@ static void test_driver_mlme(struct test_driver_data *drv,
                           __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);
 }
 
 
@@ -654,8 +633,8 @@ static void test_driver_receive_unix(int sock, void *eloop_ctx, void *sock_ctx)
 
        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) {
@@ -718,6 +697,68 @@ static int test_driver_set_generic_elem(const char *ifname, void *priv,
 }
 
 
+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;
@@ -785,8 +826,7 @@ test_driver_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
        }
        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;
@@ -802,8 +842,7 @@ test_driver_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
        }
        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;
@@ -819,8 +858,7 @@ test_driver_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
        }
        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;
@@ -968,12 +1006,13 @@ static int test_driver_set_privacy(const char *ifname, void *priv, int enabled)
 }
 
 
-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)
@@ -991,10 +1030,8 @@ static int test_driver_set_sta_vlan(void *priv, const u8 *addr,
 }
 
 
-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;
@@ -1002,14 +1039,15 @@ static int test_driver_sta_add(const char *ifname, void *priv, const u8 *addr,
 
        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;
        }
@@ -1038,7 +1076,10 @@ static int test_driver_sta_add(const char *ifname, void *priv, const u8 *addr,
 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) {
@@ -1065,7 +1106,8 @@ static void * test_driver_init(struct hostapd_data *hapd)
        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;
@@ -1080,30 +1122,43 @@ static void * test_driver_init(struct hostapd_data *hapd)
                                         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;
                }
@@ -1131,7 +1186,8 @@ static void test_driver_deinit(void *priv)
        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. */
@@ -1144,7 +1200,7 @@ static void test_driver_deinit(void *priv)
 }
 
 
-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,
@@ -1162,8 +1218,10 @@ const struct wpa_driver_ops wpa_driver_test_ops = {
        .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,
 };