Check os_snprintf() result more consistently - automatic 1
[mech_eap.git] / src / drivers / driver_wext.c
index c688874..561cdb3 100644 (file)
 #include "driver.h"
 #include "driver_wext.h"
 
-#ifdef ANDROID
-#include "android_drv.h"
-#endif /* ANDROID */
-
 static int wpa_driver_wext_flush_pmkid(void *priv);
 static int wpa_driver_wext_get_range(void *priv);
 static int wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv);
@@ -299,14 +295,6 @@ wpa_driver_wext_event_wireless_custom(void *ctx, char *custom)
                }
                wpa_supplicant_event(ctx, EVENT_STKSTART, &data);
 #endif /* CONFIG_PEERKEY */
-#ifdef ANDROID
-       } else if (os_strncmp(custom, "STOP", 4) == 0) {
-               wpa_msg(ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
-       } else if (os_strncmp(custom, "START", 5) == 0) {
-               wpa_msg(ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
-       } else if (os_strncmp(custom, "HANG", 4) == 0) {
-               wpa_msg(ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
-#endif /* ANDROID */
        }
 }
 
@@ -502,11 +490,9 @@ static void wpa_driver_wext_event_wireless(struct wpa_driver_wext_data *drv,
                                           "IWEVCUSTOM length");
                                return;
                        }
-                       buf = os_malloc(iwe->u.data.length + 1);
+                       buf = dup_binstr(custom, iwe->u.data.length);
                        if (buf == NULL)
                                return;
-                       os_memcpy(buf, custom, iwe->u.data.length);
-                       buf[iwe->u.data.length] = '\0';
                        wpa_driver_wext_event_wireless_custom(drv->ctx, buf);
                        os_free(buf);
                        break;
@@ -860,12 +846,6 @@ void * wpa_driver_wext_init(void *ctx, const char *ifname)
 
        drv->mlme_sock = -1;
 
-#ifdef ANDROID
-       drv->errors = 0;
-       drv->driver_is_started = TRUE;
-       drv->bgscan_enabled = 0;
-#endif /* ANDROID */
-
        if (wpa_driver_wext_finish_drv_init(drv) < 0)
                goto err3;
 
@@ -1414,8 +1394,8 @@ static void wpa_driver_wext_add_scan_entry(struct wpa_scan_results *res,
        if (data->ie)
                os_memcpy(pos, data->ie, data->ie_len);
 
-       tmp = os_realloc(res->res,
-                        (res->num + 1) * sizeof(struct wpa_scan_res *));
+       tmp = os_realloc_array(res->res, res->num + 1,
+                              sizeof(struct wpa_scan_res *));
        if (tmp == NULL) {
                os_free(r);
                return;
@@ -1588,8 +1568,9 @@ static int wpa_driver_wext_get_range(void *priv)
                drv->capa.max_scan_ssids = 1;
 
                wpa_printf(MSG_DEBUG, "  capabilities: key_mgmt 0x%x enc 0x%x "
-                          "flags 0x%x",
-                          drv->capa.key_mgmt, drv->capa.enc, drv->capa.flags);
+                          "flags 0x%llx",
+                          drv->capa.key_mgmt, drv->capa.enc,
+                          (unsigned long long) drv->capa.flags);
        } else {
                wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: too old (short) data - "
                           "assuming WPA is not supported");
@@ -1871,10 +1852,8 @@ static void wpa_driver_wext_disconnect(struct wpa_driver_wext_data *drv)
 {
        struct iwreq iwr;
        const u8 null_bssid[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
-#ifndef ANDROID
        u8 ssid[32];
        int i;
-#endif /* ANDROID */
 
        /*
         * Only force-disconnect when the card is in infrastructure mode,
@@ -1895,7 +1874,6 @@ static void wpa_driver_wext_disconnect(struct wpa_driver_wext_data *drv)
                                   "selection on disconnect");
                }
 
-#ifndef ANDROID
                if (drv->cfg80211) {
                        /*
                         * cfg80211 supports SIOCSIWMLME commands, so there is
@@ -1921,7 +1899,6 @@ static void wpa_driver_wext_disconnect(struct wpa_driver_wext_data *drv)
                        wpa_printf(MSG_DEBUG, "WEXT: Failed to set bogus "
                                   "SSID to disconnect");
                }
-#endif /* ANDROID */
        }
 }
 
@@ -1938,18 +1915,6 @@ static int wpa_driver_wext_deauthenticate(void *priv, const u8 *addr,
 }
 
 
-static int wpa_driver_wext_disassociate(void *priv, const u8 *addr,
-                                       int reason_code)
-{
-       struct wpa_driver_wext_data *drv = priv;
-       int ret;
-       wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
-       ret = wpa_driver_wext_mlme(drv, addr, IW_MLME_DISASSOC, reason_code);
-       wpa_driver_wext_disconnect(drv);
-       return ret;
-}
-
-
 static int wpa_driver_wext_set_gen_ie(void *priv, const u8 *ie,
                                      size_t ie_len)
 {
@@ -1974,15 +1939,15 @@ static int wpa_driver_wext_set_gen_ie(void *priv, const u8 *ie,
 int wpa_driver_wext_cipher2wext(int cipher)
 {
        switch (cipher) {
-       case CIPHER_NONE:
+       case WPA_CIPHER_NONE:
                return IW_AUTH_CIPHER_NONE;
-       case CIPHER_WEP40:
+       case WPA_CIPHER_WEP40:
                return IW_AUTH_CIPHER_WEP40;
-       case CIPHER_TKIP:
+       case WPA_CIPHER_TKIP:
                return IW_AUTH_CIPHER_TKIP;
-       case CIPHER_CCMP:
+       case WPA_CIPHER_CCMP:
                return IW_AUTH_CIPHER_CCMP;
-       case CIPHER_WEP104:
+       case WPA_CIPHER_WEP104:
                return IW_AUTH_CIPHER_WEP104;
        default:
                return 0;
@@ -1993,10 +1958,10 @@ int wpa_driver_wext_cipher2wext(int cipher)
 int wpa_driver_wext_keymgmt2wext(int keymgmt)
 {
        switch (keymgmt) {
-       case KEY_MGMT_802_1X:
-       case KEY_MGMT_802_1X_NO_WPA:
+       case WPA_KEY_MGMT_IEEE8021X:
+       case WPA_KEY_MGMT_IEEE8021X_NO_WPA:
                return IW_AUTH_KEY_MGMT_802_1X;
-       case KEY_MGMT_PSK:
+       case WPA_KEY_MGMT_PSK:
                return IW_AUTH_KEY_MGMT_PSK;
        default:
                return 0;
@@ -2063,7 +2028,11 @@ int wpa_driver_wext_associate(void *priv,
                 * Stop cfg80211 from trying to associate before we are done
                 * with all parameters.
                 */
-               wpa_driver_wext_set_ssid(drv, (u8 *) "", 0);
+               if (wpa_driver_wext_set_ssid(drv, (u8 *) "", 0) < 0) {
+                       wpa_printf(MSG_DEBUG,
+                                  "WEXT: Failed to clear SSID to stop pending cfg80211 association attempts (if any)");
+                       /* continue anyway */
+               }
        }
 
        if (wpa_driver_wext_set_drop_unencrypted(drv, params->drop_unencrypted)
@@ -2092,12 +2061,12 @@ int wpa_driver_wext_associate(void *priv,
        if (wpa_driver_wext_set_gen_ie(drv, params->wpa_ie, params->wpa_ie_len)
            < 0)
                ret = -1;
-       if (params->wpa_ie == NULL || params->wpa_ie_len == 0)
-               value = IW_AUTH_WPA_VERSION_DISABLED;
-       else if (params->wpa_ie[0] == WLAN_EID_RSN)
+       if (params->wpa_proto & WPA_PROTO_RSN)
                value = IW_AUTH_WPA_VERSION_WPA2;
-       else
+       else if (params->wpa_proto & WPA_PROTO_WPA)
                value = IW_AUTH_WPA_VERSION_WPA;
+       else
+               value = IW_AUTH_WPA_VERSION_DISABLED;
        if (wpa_driver_wext_set_auth_param(drv,
                                           IW_AUTH_WPA_VERSION, value) < 0)
                ret = -1;
@@ -2113,10 +2082,10 @@ int wpa_driver_wext_associate(void *priv,
        if (wpa_driver_wext_set_auth_param(drv,
                                           IW_AUTH_KEY_MGMT, value) < 0)
                ret = -1;
-       value = params->key_mgmt_suite != KEY_MGMT_NONE ||
-               params->pairwise_suite != CIPHER_NONE ||
-               params->group_suite != CIPHER_NONE ||
-               params->wpa_ie_len;
+       value = params->key_mgmt_suite != WPA_KEY_MGMT_NONE ||
+               params->pairwise_suite != WPA_CIPHER_NONE ||
+               params->group_suite != WPA_CIPHER_NONE ||
+               (params->wpa_proto & (WPA_PROTO_RSN | WPA_PROTO_WPA));
        if (wpa_driver_wext_set_auth_param(drv,
                                           IW_AUTH_PRIVACY_INVOKED, value) < 0)
                ret = -1;
@@ -2124,8 +2093,8 @@ int wpa_driver_wext_associate(void *priv,
        /* Allow unencrypted EAPOL messages even if pairwise keys are set when
         * not using WPA. IEEE 802.1X specifies that these frames are not
         * encrypted, but WPA encrypts them when pairwise keys are in use. */
-       if (params->key_mgmt_suite == KEY_MGMT_802_1X ||
-           params->key_mgmt_suite == KEY_MGMT_PSK)
+       if (params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
+           params->key_mgmt_suite == WPA_KEY_MGMT_PSK)
                allow_unencrypted_eapol = 0;
        else
                allow_unencrypted_eapol = 1;
@@ -2151,7 +2120,8 @@ int wpa_driver_wext_associate(void *priv,
        if (wpa_driver_wext_set_auth_param(drv, IW_AUTH_MFP, value) < 0)
                ret = -1;
 #endif /* CONFIG_IEEE80211W */
-       if (params->freq && wpa_driver_wext_set_freq(drv, params->freq) < 0)
+       if (params->freq.freq &&
+           wpa_driver_wext_set_freq(drv, params->freq.freq) < 0)
                ret = -1;
        if (!drv->cfg80211 &&
            wpa_driver_wext_set_ssid(drv, params->ssid, params->ssid_len) < 0)
@@ -2352,129 +2322,64 @@ static const char * wext_get_radio_name(void *priv)
 }
 
 
-#ifdef ANDROID
-
-static int android_wext_cmd(struct wpa_driver_wext_data *drv, const char *cmd)
+static int wpa_driver_wext_signal_poll(void *priv, struct wpa_signal_info *si)
 {
+       struct wpa_driver_wext_data *drv = priv;
+       struct iw_statistics stats;
        struct iwreq iwr;
-       char buf[MAX_DRV_CMD_SIZE];
-       int ret;
+
+       os_memset(si, 0, sizeof(*si));
+       si->current_signal = -9999;
+       si->current_noise = 9999;
+       si->chanwidth = CHAN_WIDTH_UNKNOWN;
 
        os_memset(&iwr, 0, sizeof(iwr));
        os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+       iwr.u.data.pointer = (caddr_t) &stats;
+       iwr.u.data.length = sizeof(stats);
+       iwr.u.data.flags = 1;
 
-       os_memset(buf, 0, sizeof(buf));
-       os_strlcpy(buf, cmd, sizeof(buf));
-
-       iwr.u.data.pointer = buf;
-       iwr.u.data.length = sizeof(buf);
-
-       ret = ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr);
-
-       if (ret < 0) {
-               wpa_printf(MSG_ERROR, "%s failed (%d): %s", __func__, ret,
-                          cmd);
-               drv->errors++;
-               if (drv->errors > DRV_NUMBER_SEQUENTIAL_ERRORS) {
-                       drv->errors = 0;
-                       wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE
-                               "HANGED");
-               }
-               return ret;
+       if (ioctl(drv->ioctl_sock, SIOCGIWSTATS, &iwr) < 0) {
+               wpa_printf(MSG_ERROR, "WEXT: SIOCGIWSTATS: %s",
+                          strerror(errno));
+               return -1;
        }
 
-       drv->errors = 0;
+       si->current_signal = stats.qual.level -
+               ((stats.qual.updated & IW_QUAL_DBM) ? 0x100 : 0);
+       si->current_noise = stats.qual.noise -
+               ((stats.qual.updated & IW_QUAL_DBM) ? 0x100 : 0);
        return 0;
 }
 
 
-static int wext_sched_scan(void *priv, struct wpa_driver_scan_params *params,
-                          u32 interval)
+static int wpa_driver_wext_status(void *priv, char *buf, size_t buflen)
 {
        struct wpa_driver_wext_data *drv = priv;
-       struct iwreq iwr;
-       int ret = 0, i = 0, bp;
-       char buf[WEXT_PNO_MAX_COMMAND_SIZE];
-
-       bp = WEXT_PNOSETUP_HEADER_SIZE;
-       os_memcpy(buf, WEXT_PNOSETUP_HEADER, bp);
-       buf[bp++] = WEXT_PNO_TLV_PREFIX;
-       buf[bp++] = WEXT_PNO_TLV_VERSION;
-       buf[bp++] = WEXT_PNO_TLV_SUBVERSION;
-       buf[bp++] = WEXT_PNO_TLV_RESERVED;
-
-       while (i < WEXT_PNO_AMOUNT && (size_t) i < params->num_ssids) {
-               /*
-                * Check that there is enough space needed for 1 more SSID, the
-                * other sections and null termination.
-                */
-               if ((bp + WEXT_PNO_SSID_HEADER_SIZE + IW_ESSID_MAX_SIZE +
-                    WEXT_PNO_NONSSID_SECTIONS_SIZE + 1) >= (int) sizeof(buf))
-                       break;
-
-               wpa_hexdump_ascii(MSG_DEBUG, "For PNO Scan",
-                                 params->ssids[i].ssid,
-                                 params->ssids[i].ssid_len);
-               buf[bp++] = WEXT_PNO_SSID_SECTION;
-               buf[bp++] = params->ssids[i].ssid_len;
-               os_memcpy(&buf[bp], params->ssids[i].ssid,
-                         params->ssids[i].ssid_len);
-               bp += params->ssids[i].ssid_len;
-               i++;
-       }
-
-       buf[bp++] = WEXT_PNO_SCAN_INTERVAL_SECTION;
-       /* TODO: consider using interval parameter (interval in msec) instead
-        * of hardcoded value here */
-       os_snprintf(&buf[bp], WEXT_PNO_SCAN_INTERVAL_LENGTH + 1, "%x",
-                   WEXT_PNO_SCAN_INTERVAL);
-       bp += WEXT_PNO_SCAN_INTERVAL_LENGTH;
-
-       buf[bp++] = WEXT_PNO_REPEAT_SECTION;
-       os_snprintf(&buf[bp], WEXT_PNO_REPEAT_LENGTH + 1, "%x",
-                   WEXT_PNO_REPEAT);
-       bp += WEXT_PNO_REPEAT_LENGTH;
-
-       buf[bp++] = WEXT_PNO_MAX_REPEAT_SECTION;
-       os_snprintf(&buf[bp], WEXT_PNO_MAX_REPEAT_LENGTH + 1, "%x",
-                   WEXT_PNO_MAX_REPEAT);
-       bp += WEXT_PNO_MAX_REPEAT_LENGTH + 1;
+       int res;
+       char *pos, *end;
+       unsigned char addr[ETH_ALEN];
 
-       os_memset(&iwr, 0, sizeof(iwr));
-       os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
-       iwr.u.data.pointer = buf;
-       iwr.u.data.length = bp;
-
-       ret = ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr);
-       if (ret < 0) {
-               wpa_printf(MSG_ERROR, "ioctl[SIOCSIWPRIV] (pnosetup): %d",
-                          ret);
-               drv->errors++;
-               if (drv->errors > DRV_NUMBER_SEQUENTIAL_ERRORS) {
-                       drv->errors = 0;
-                       wpa_msg(drv->ctx, MSG_INFO,
-                               WPA_EVENT_DRIVER_STATE "HANGED");
-               }
-               return ret;
-       }
-
-       drv->errors = 0;
-       drv->bgscan_enabled = 1;
+       pos = buf;
+       end = buf + buflen;
 
-       return android_wext_cmd(drv, "PNOFORCE 1");
-}
+       if (linux_get_ifhwaddr(drv->ioctl_sock, drv->ifname, addr))
+               return -1;
 
+       res = os_snprintf(pos, end - pos,
+                         "ifindex=%d\n"
+                         "ifname=%s\n"
+                         "addr=" MACSTR "\n",
+                         drv->ifindex,
+                         drv->ifname,
+                         MAC2STR(addr));
+       if (os_snprintf_error(end - pos, res))
+               return pos - buf;
+       pos += res;
 
-static int wext_stop_sched_scan(void *priv)
-{
-       struct wpa_driver_wext_data *drv = priv;
-       drv->bgscan_enabled = 0;
-       return android_wext_cmd(drv, "PNOFORCE 0");
+       return pos - buf;
 }
 
-#endif /* ANDROID */
-
-
 const struct wpa_driver_ops wpa_driver_wext_ops = {
        .name = "wext",
        .desc = "Linux wireless extensions (generic)",
@@ -2485,7 +2390,6 @@ const struct wpa_driver_ops wpa_driver_wext_ops = {
        .scan2 = wpa_driver_wext_scan,
        .get_scan_results2 = wpa_driver_wext_get_scan_results,
        .deauthenticate = wpa_driver_wext_deauthenticate,
-       .disassociate = wpa_driver_wext_disassociate,
        .associate = wpa_driver_wext_associate,
        .init = wpa_driver_wext_init,
        .deinit = wpa_driver_wext_deinit,
@@ -2495,8 +2399,6 @@ const struct wpa_driver_ops wpa_driver_wext_ops = {
        .get_capa = wpa_driver_wext_get_capa,
        .set_operstate = wpa_driver_wext_set_operstate,
        .get_radio_name = wext_get_radio_name,
-#ifdef ANDROID
-       .sched_scan = wext_sched_scan,
-       .stop_sched_scan = wext_stop_sched_scan,
-#endif /* ANDROID */
+       .signal_poll = wpa_driver_wext_signal_poll,
+       .status = wpa_driver_wext_status,
 };