Merge driver ops set_wps_beacon_ie and set_wps_probe_resp_ie
[libeap.git] / src / drivers / driver_atheros.c
index 1de3a71..c3e09c4 100644 (file)
 
 #include "wireless_copy.h"
 
-#include "../hostapd/hostapd.h"
-#include "../hostapd/config.h"
-#include "../hostapd/sta_flags.h"
 #include "driver.h"
 #include "eloop.h"
 #include "priv_netlink.h"
 #include "l2_packet/l2_packet.h"
 #include "common/ieee802_11_defs.h"
+#include "netlink.h"
 
 
 struct madwifi_driver_data {
@@ -76,7 +74,7 @@ struct madwifi_driver_data {
        struct l2_packet_data *sock_xmit;       /* raw packet xmit socket */
        struct l2_packet_data *sock_recv;       /* raw packet recv socket */
        int     ioctl_sock;                     /* socket for ioctl() use */
-       int     wext_sock;                      /* socket for wireless events */
+       struct netlink_data *netlink;
        int     we_version;
        u8      acct_mac[ETH_ALEN];
        struct hostap_sta_driver_data acct_data;
@@ -192,13 +190,12 @@ ether_sprintf(const u8 *addr)
  * Configure WPA parameters.
  */
 static int
-madwifi_configure_wpa(struct madwifi_driver_data *drv)
+madwifi_configure_wpa(struct madwifi_driver_data *drv,
+                     struct wpa_bss_params *params)
 {
-       struct hostapd_data *hapd = drv->hapd;
-       struct hostapd_bss_config *conf = hapd->conf;
        int v;
 
-       switch (conf->wpa_group) {
+       switch (params->wpa_group) {
        case WPA_CIPHER_CCMP:
                v = IEEE80211_CIPHER_AES_CCM;
                break;
@@ -216,7 +213,7 @@ madwifi_configure_wpa(struct madwifi_driver_data *drv)
                break;
        default:
                wpa_printf(MSG_ERROR, "Unknown group key cipher %u",
-                          conf->wpa_group);
+                          params->wpa_group);
                return -1;
        }
        wpa_printf(MSG_DEBUG, "%s: group key cipher=%d", __func__, v);
@@ -226,7 +223,7 @@ madwifi_configure_wpa(struct madwifi_driver_data *drv)
        }
        if (v == IEEE80211_CIPHER_WEP) {
                /* key length is done only for specific ciphers */
-               v = (conf->wpa_group == WPA_CIPHER_WEP104 ? 13 : 5);
+               v = (params->wpa_group == WPA_CIPHER_WEP104 ? 13 : 5);
                if (set80211param(drv, IEEE80211_PARAM_MCASTKEYLEN, v)) {
                        printf("Unable to set group key length to %u\n", v);
                        return -1;
@@ -234,11 +231,11 @@ madwifi_configure_wpa(struct madwifi_driver_data *drv)
        }
 
        v = 0;
-       if (conf->wpa_pairwise & WPA_CIPHER_CCMP)
+       if (params->wpa_pairwise & WPA_CIPHER_CCMP)
                v |= 1<<IEEE80211_CIPHER_AES_CCM;
-       if (conf->wpa_pairwise & WPA_CIPHER_TKIP)
+       if (params->wpa_pairwise & WPA_CIPHER_TKIP)
                v |= 1<<IEEE80211_CIPHER_TKIP;
-       if (conf->wpa_pairwise & WPA_CIPHER_NONE)
+       if (params->wpa_pairwise & WPA_CIPHER_NONE)
                v |= 1<<IEEE80211_CIPHER_NONE;
        wpa_printf(MSG_DEBUG, "%s: pairwise key ciphers=0x%x", __func__, v);
        if (set80211param(drv, IEEE80211_PARAM_UCASTCIPHERS, v)) {
@@ -247,26 +244,27 @@ madwifi_configure_wpa(struct madwifi_driver_data *drv)
        }
 
        wpa_printf(MSG_DEBUG, "%s: key management algorithms=0x%x",
-                  __func__, conf->wpa_key_mgmt);
-       if (set80211param(drv, IEEE80211_PARAM_KEYMGTALGS, conf->wpa_key_mgmt)) {
+                  __func__, params->wpa_key_mgmt);
+       if (set80211param(drv, IEEE80211_PARAM_KEYMGTALGS,
+                         params->wpa_key_mgmt)) {
                printf("Unable to set key management algorithms to 0x%x\n",
-                       conf->wpa_key_mgmt);
+                       params->wpa_key_mgmt);
                return -1;
        }
 
        v = 0;
-       if (conf->rsn_preauth)
+       if (params->rsn_preauth)
                v |= BIT(0);
        wpa_printf(MSG_DEBUG, "%s: rsn capabilities=0x%x",
-                  __func__, conf->rsn_preauth);
+                  __func__, params->rsn_preauth);
        if (set80211param(drv, IEEE80211_PARAM_RSNCAPS, v)) {
                printf("Unable to set RSN capabilities to 0x%x\n", v);
                return -1;
        }
 
-       wpa_printf(MSG_DEBUG, "%s: enable WPA=0x%x", __func__, conf->wpa);
-       if (set80211param(drv, IEEE80211_PARAM_WPA, conf->wpa)) {
-               printf("Unable to set WPA to %u\n", conf->wpa);
+       wpa_printf(MSG_DEBUG, "%s: enable WPA=0x%x", __func__, params->wpa);
+       if (set80211param(drv, IEEE80211_PARAM_WPA, params->wpa)) {
+               printf("Unable to set WPA to %u\n", params->wpa);
                return -1;
        }
        return 0;
@@ -306,32 +304,30 @@ madwifi_set_iface_flags(void *priv, int dev_up)
 }
 
 static int
-madwifi_set_ieee8021x(const char *ifname, void *priv, int enabled)
+madwifi_set_ieee8021x(void *priv, struct wpa_bss_params *params)
 {
        struct madwifi_driver_data *drv = priv;
-       struct hostapd_data *hapd = drv->hapd;
-       struct hostapd_bss_config *conf = hapd->conf;
 
-       wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
+       wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, params->enabled);
 
-       if (!enabled) {
+       if (!params->enabled) {
                /* XXX restore state */
                return set80211param(priv, IEEE80211_PARAM_AUTHMODE,
                        IEEE80211_AUTH_AUTO);
        }
-       if (!conf->wpa && !conf->ieee802_1x) {
-               hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER,
+       if (!params->wpa && !params->ieee802_1x) {
+               hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER,
                        HOSTAPD_LEVEL_WARNING, "No 802.1X or WPA enabled!");
                return -1;
        }
-       if (conf->wpa && madwifi_configure_wpa(drv) != 0) {
-               hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER,
+       if (params->wpa && madwifi_configure_wpa(drv, params) != 0) {
+               hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER,
                        HOSTAPD_LEVEL_WARNING, "Error configuring WPA state!");
                return -1;
        }
        if (set80211param(priv, IEEE80211_PARAM_AUTHMODE,
-               (conf->wpa ?  IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) {
-               hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER,
+               (params->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) {
+               hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER,
                        HOSTAPD_LEVEL_WARNING, "Error enabling WPA/802.1X!");
                return -1;
        }
@@ -379,9 +375,9 @@ madwifi_sta_set_flags(void *priv, const u8 *addr, int total_flags,
                      int flags_or, int flags_and)
 {
        /* For now, only support setting Authorized flag */
-       if (flags_or & WLAN_STA_AUTHORIZED)
+       if (flags_or & WPA_STA_AUTHORIZED)
                return madwifi_set_sta_authorized(priv, addr, 1);
-       if (!(flags_and & WLAN_STA_AUTHORIZED))
+       if (!(flags_and & WPA_STA_AUTHORIZED))
                return madwifi_set_sta_authorized(priv, addr, 0);
        return 0;
 }
@@ -719,22 +715,21 @@ madwifi_set_wps_ie(void *priv, const u8 *ie, size_t len, u32 frametype)
 }
 
 static int
-madwifi_set_wps_beacon_ie(const char *ifname, void *priv, const u8 *ie,
-                         size_t len)
+madwifi_set_ap_wps_ie(const char *ifname, void *priv,
+                     const struct wpabuf *beacon,
+                     const struct wpabuf *proberesp)
 {
-       return madwifi_set_wps_ie(priv, ie, len, IEEE80211_APPIE_FRAME_BEACON);
-}
-
-static int
-madwifi_set_wps_probe_resp_ie(const char *ifname, void *priv, const u8 *ie,
-                             size_t len)
-{
-       return madwifi_set_wps_ie(priv, ie, len,
+       if (madwifi_set_wps_ie(priv, beacon ? wpabuf_head(beacon) : NULL,
+                              beacon ? wpabuf_len(beacon) : 0,
+                              IEEE80211_APPIE_FRAME_BEACON))
+               return -1;
+       return madwifi_set_wps_ie(priv,
+                                 proberesp ? wpabuf_head(proberesp) : NULL,
+                                 proberesp ? wpabuf_len(proberesp): 0,
                                  IEEE80211_APPIE_FRAME_PROBE_RESP);
 }
 #else /* CONFIG_WPS */
-#define madwifi_set_wps_beacon_ie NULL
-#define madwifi_set_wps_probe_resp_ie NULL
+#define madwifi_set_ap_wps_ie NULL
 #endif /* CONFIG_WPS */
 
 static int
@@ -812,7 +807,12 @@ madwifi_wireless_event_wireless_custom(struct madwifi_driver_data *drv,
                }
                pos += 5;
                if (hwaddr_aton(pos, addr) == 0) {
-                       hostapd_michael_mic_failure(drv->hapd, addr);
+                       union wpa_event_data data;
+                       os_memset(&data, 0, sizeof(data));
+                       data.michael_mic_failure.unicast = 1;
+                       data.michael_mic_failure.src = addr;
+                       wpa_supplicant_event(drv->hapd,
+                                            EVENT_MICHAEL_MIC_FAILURE, &data);
                } else {
                        wpa_printf(MSG_DEBUG,
                                   "MLME-MICHAELMICFAILURE.indication "
@@ -847,7 +847,7 @@ madwifi_wireless_event_wireless_custom(struct madwifi_driver_data *drv,
                /* PROBLEM! this event is received for ALL BSSs ...
                 * so all are enabled for WPS... ugh.
                 */
-               hostapd_button_pushed(drv->hapd);
+               wpa_supplicant_event(drv->hapd, EVENT_WPS_BUTTON_PUSHED, NULL);
        } else if (strncmp(custom, "Manage.prob_req ", 16) == 0) {
                /*
                 * Atheros driver uses a hack to pass Probe Request frames as a
@@ -935,28 +935,18 @@ madwifi_wireless_event_wireless(struct madwifi_driver_data *drv,
 
 
 static void
-madwifi_wireless_event_rtm_newlink(struct madwifi_driver_data *drv,
-                                              struct nlmsghdr *h, int len)
+madwifi_wireless_event_rtm_newlink(void *ctx,
+                                  struct ifinfomsg *ifi, u8 *buf, size_t len)
 {
-       struct ifinfomsg *ifi;
-       int attrlen, nlmsg_len, rta_len;
-       struct rtattr * attr;
-
-       if (len < (int) sizeof(*ifi))
-               return;
-
-       ifi = NLMSG_DATA(h);
+       struct madwifi_driver_data *drv = ctx;
+       int attrlen, rta_len;
+       struct rtattr *attr;
 
        if (ifi->ifi_index != drv->ifindex)
                return;
 
-       nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
-
-       attrlen = h->nlmsg_len - nlmsg_len;
-       if (attrlen < 0)
-               return;
-
-       attr = (struct rtattr *) (((char *) ifi) + nlmsg_len);
+       attrlen = len;
+       attr = (struct rtattr *) buf;
 
        rta_len = RTA_ALIGN(sizeof(struct rtattr));
        while (RTA_OK(attr, attrlen)) {
@@ -970,55 +960,6 @@ madwifi_wireless_event_rtm_newlink(struct madwifi_driver_data *drv,
 }
 
 
-static void
-madwifi_wireless_event_receive(int sock, void *eloop_ctx, void *sock_ctx)
-{
-       char buf[256];
-       int left;
-       struct sockaddr_nl from;
-       socklen_t fromlen;
-       struct nlmsghdr *h;
-       struct madwifi_driver_data *drv = eloop_ctx;
-
-       fromlen = sizeof(from);
-       left = recvfrom(sock, buf, sizeof(buf), MSG_DONTWAIT,
-                       (struct sockaddr *) &from, &fromlen);
-       if (left < 0) {
-               if (errno != EINTR && errno != EAGAIN)
-                       perror("recvfrom(netlink)");
-               return;
-       }
-
-       h = (struct nlmsghdr *) buf;
-       while (left >= (int) sizeof(*h)) {
-               int len, plen;
-
-               len = h->nlmsg_len;
-               plen = len - sizeof(*h);
-               if (len > left || plen < 0) {
-                       printf("Malformed netlink message: "
-                              "len=%d left=%d plen=%d\n",
-                              len, left, plen);
-                       break;
-               }
-
-               switch (h->nlmsg_type) {
-               case RTM_NEWLINK:
-                       madwifi_wireless_event_rtm_newlink(drv, h, plen);
-                       break;
-               }
-
-               len = NLMSG_ALIGN(len);
-               left -= len;
-               h = (struct nlmsghdr *) ((char *) h + len);
-       }
-
-       if (left > 0) {
-               printf("%d extra bytes in the end of netlink message\n", left);
-       }
-}
-
-
 static int
 madwifi_get_we_version(struct madwifi_driver_data *drv)
 {
@@ -1068,45 +1009,25 @@ madwifi_get_we_version(struct madwifi_driver_data *drv)
 static int
 madwifi_wireless_event_init(struct madwifi_driver_data *drv)
 {
-       int s;
-       struct sockaddr_nl local;
+       struct netlink_config *cfg;
 
        madwifi_get_we_version(drv);
 
-       drv->wext_sock = -1;
-
-       s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
-       if (s < 0) {
-               perror("socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE)");
+       cfg = os_zalloc(sizeof(*cfg));
+       if (cfg == NULL)
                return -1;
-       }
-
-       memset(&local, 0, sizeof(local));
-       local.nl_family = AF_NETLINK;
-       local.nl_groups = RTMGRP_LINK;
-       if (bind(s, (struct sockaddr *) &local, sizeof(local)) < 0) {
-               perror("bind(netlink)");
-               close(s);
+       cfg->ctx = drv;
+       cfg->newlink_cb = madwifi_wireless_event_rtm_newlink;
+       drv->netlink = netlink_init(cfg);
+       if (drv->netlink == NULL) {
+               os_free(cfg);
                return -1;
        }
 
-       eloop_register_read_sock(s, madwifi_wireless_event_receive, drv, NULL);
-       drv->wext_sock = s;
-
        return 0;
 }
 
 
-static void
-madwifi_wireless_event_deinit(struct madwifi_driver_data *drv)
-{
-       if (drv->wext_sock < 0)
-               return;
-       eloop_unregister_read_sock(drv->wext_sock);
-       close(drv->wext_sock);
-}
-
-
 static int
 madwifi_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len,
                   int encrypt, const u8 *own_addr)
@@ -1239,7 +1160,7 @@ madwifi_deinit(void *priv)
 {
        struct madwifi_driver_data *drv = priv;
 
-       madwifi_wireless_event_deinit(drv);
+       netlink_deinit(drv->netlink);
        (void) madwifi_set_iface_flags(drv, 0);
        if (drv->ioctl_sock >= 0)
                close(drv->ioctl_sock);
@@ -1327,6 +1248,5 @@ const struct wpa_driver_ops wpa_driver_atheros_ops = {
        .set_countermeasures    = madwifi_set_countermeasures,
        .sta_clear_stats        = madwifi_sta_clear_stats,
        .commit                 = madwifi_commit,
-       .set_wps_beacon_ie      = madwifi_set_wps_beacon_ie,
-       .set_wps_probe_resp_ie  = madwifi_set_wps_probe_resp_ie,
+       .set_ap_wps_ie          = madwifi_set_ap_wps_ie,
 };