Accumulative patch from commit 20a0b03debef66cc57b0c34a05f8be5229be907c
atheros: Fix auth_alg configuration for static WEP
nl80211: Implement set_rate_sets for non-hostapd AP case
nl80211: Enable more AP callbacks for non-hostapd AP mode
nl80211: Re-order functions to group AP/hostapd specific code
Remove compiler warning for non-P2P builds
random: Add support for maintaining internal entropy store over restarts
Fix a compiler warning on WPS-AP-without-UPnP builds
P2P: Retry provision discovery requests in IDLE state
P2P: Add callback for provision discovery failure
P2P: Add wpas_notify_p2p_provision_discovery()
P2P: Add group started notification
DBus: Move wpas_dbus_new_decompose_object_path()
DBus: Refactor array adding, add binary arrays
DBus: Add support for P2P primitives
DBus: Fix some typos on comments
Fix CONFIG_AP=y build without CONFIG_P2P=y
Fix non-P2P D-Bus build
nl80211: Add support for driver-based PMKSA cache
P2P: Start GO without extra scan step
Remove a compiler warning on uninitialized variable
Add EVENT_RX_ACTION handler for hostapd
Fix hostapd build without NEED_AP_MLME=y
Fix AP selection to check privacy mismatch and IBSS with WPA/RSN IE
bsd: Fix set_key() sequence number endian issue
Add a copyright and license statement for a radiotap header file
Use nl80211 as an example instead of WEXT
Add notes for CONFIG_WPS_ER build configuration option
Fix CONFIG_NO_WPA_PASSPHRASE=y build
hostapd: Don't mask out non-symmetric STA HT caps
P2P: Enable P2P capability advertisement on D-Bus
P2P: Update D-Bus network object semantics during group formation
P2P: Show P2P peer signal level in D-Bus P2P device properties
P2P: Fix P2P device signal level type in D-Bus
P2P: Add dissasoc_low_ack in P2P device properties
P2P: More complete persistent group management over D-Bus
P2P: Add WpsFailed signal in P2P D-Bus
P2P: Update listen and operating channel from P2P D-Bus
P2P: Fix WpsFailed signal in P2P D-Bus
atheros: Fix glibc 'invalid pointer' error when WPA_TRACE is enabled
Clear WPA and EAPOL state machine config pointer on network removal
20a0b03debef66cc57b0c34a05f8be5229be907c
Change-Id: I2b83bf86ba9c7a9a218638be7b4de31d209cdde1
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 2a3efa4..c7dbdc1 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -2243,6 +2243,18 @@
int (*signal_poll)(void *priv, struct wpa_signal_info *signal_info);
/**
+ * set_authmode - Set authentication algorithm(s) for static WEP
+ * @priv: Private driver interface data
+ * @authmode: 1=Open System, 2=Shared Key, 3=both
+ * Returns: 0 on success, -1 on failure
+ *
+ * This function can be used to set authentication algorithms for AP
+ * mode when static WEP is used. If the driver uses user space MLME/SME
+ * implementation, there is no need to implement this function.
+ */
+ int (*set_authmode)(void *priv, int authmode);
+
+ /**
* driver_cmd - execute driver-specific command
* @priv: private driver interface data
* @cmd: command to execute
diff --git a/src/drivers/driver_atheros.c b/src/drivers/driver_atheros.c
index 6ac1cea..1e78f6e 100644
--- a/src/drivers/driver_atheros.c
+++ b/src/drivers/driver_atheros.c
@@ -1116,7 +1116,7 @@
drv->we_version = range->we_version_compiled;
}
- free(range);
+ os_free(range);
return 0;
}
@@ -1357,6 +1357,23 @@
return linux_set_iface_flags(drv->ioctl_sock, drv->iface, 1);
}
+static int atheros_set_authmode(void *priv, int auth_algs)
+{
+ int authmode;
+
+ if ((auth_algs & WPA_AUTH_ALG_OPEN) &&
+ (auth_algs & WPA_AUTH_ALG_SHARED))
+ authmode = IEEE80211_AUTH_AUTO;
+ else if (auth_algs & WPA_AUTH_ALG_OPEN)
+ authmode = IEEE80211_AUTH_OPEN;
+ else if (auth_algs & WPA_AUTH_ALG_SHARED)
+ authmode = IEEE80211_AUTH_SHARED;
+ else
+ return -1;
+
+ return set80211param(priv, IEEE80211_PARAM_AUTHMODE, authmode);
+}
+
const struct wpa_driver_ops wpa_driver_atheros_ops = {
.name = "atheros",
.hapd_init = atheros_init,
@@ -1378,4 +1395,5 @@
.sta_clear_stats = atheros_sta_clear_stats,
.commit = atheros_commit,
.set_ap_wps_ie = atheros_set_ap_wps_ie,
+ .set_authmode = atheros_set_authmode,
};
diff --git a/src/drivers/driver_bsd.c b/src/drivers/driver_bsd.c
index 1b52865..4596a51 100644
--- a/src/drivers/driver_bsd.c
+++ b/src/drivers/driver_bsd.c
@@ -345,8 +345,20 @@
if (wk.ik_keyix != IEEE80211_KEYIX_NONE && set_tx)
wk.ik_flags |= IEEE80211_KEY_DEFAULT;
wk.ik_keylen = key_len;
- if (seq)
+ if (seq) {
+#ifdef WORDS_BIGENDIAN
+ /*
+ * wk.ik_keyrsc is in host byte order (big endian), need to
+ * swap it to match with the byte order used in WPA.
+ */
+ int i;
+ u8 *keyrsc = (u8 *) &wk.ik_keyrsc;
+ for (i = 0; i < seq_len; i++)
+ keyrsc[WPA_KEY_RSC_LEN - i - 1] = seq[i];
+#else /* WORDS_BIGENDIAN */
os_memcpy(&wk.ik_keyrsc, seq, seq_len);
+#endif /* WORDS_BIGENDIAN */
+ }
os_memcpy(wk.ik_keydata, key, key_len);
return set80211var(priv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk));
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index b4f01fa..cfc9372 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -5043,70 +5043,17 @@
}
-#ifdef HOSTAPD
-
-static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
+/* Set kernel driver on given frequency (MHz) */
+static int i802_set_freq(void *priv, struct hostapd_freq_params *freq)
{
- int i;
- int *old;
-
- wpa_printf(MSG_DEBUG, "nl80211: Add own interface ifindex %d",
- ifidx);
- for (i = 0; i < drv->num_if_indices; i++) {
- if (drv->if_indices[i] == 0) {
- drv->if_indices[i] = ifidx;
- return;
- }
- }
-
- if (drv->if_indices != drv->default_if_indices)
- old = drv->if_indices;
- else
- old = NULL;
-
- drv->if_indices = os_realloc(old,
- sizeof(int) * (drv->num_if_indices + 1));
- if (!drv->if_indices) {
- if (!old)
- drv->if_indices = drv->default_if_indices;
- else
- drv->if_indices = old;
- wpa_printf(MSG_ERROR, "Failed to reallocate memory for "
- "interfaces");
- wpa_printf(MSG_ERROR, "Ignoring EAPOL on interface %d", ifidx);
- return;
- } else if (!old)
- os_memcpy(drv->if_indices, drv->default_if_indices,
- sizeof(drv->default_if_indices));
- drv->if_indices[drv->num_if_indices] = ifidx;
- drv->num_if_indices++;
+ struct i802_bss *bss = priv;
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+ return wpa_driver_nl80211_set_freq(drv, freq->freq, freq->ht_enabled,
+ freq->sec_channel_offset);
}
-static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
-{
- int i;
-
- for (i = 0; i < drv->num_if_indices; i++) {
- if (drv->if_indices[i] == ifidx) {
- drv->if_indices[i] = 0;
- break;
- }
- }
-}
-
-
-static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
-{
- int i;
-
- for (i = 0; i < drv->num_if_indices; i++)
- if (drv->if_indices[i] == ifidx)
- return 1;
-
- return 0;
-}
-
+#if defined(HOSTAPD) || defined(CONFIG_AP)
static inline int min_int(int a, int b)
{
@@ -5193,20 +5140,6 @@
return -ENOBUFS;
}
-#endif /* HOSTAPD */
-
-
-/* Set kernel driver on given frequency (MHz) */
-static int i802_set_freq(void *priv, struct hostapd_freq_params *freq)
-{
- struct i802_bss *bss = priv;
- struct wpa_driver_nl80211_data *drv = bss->drv;
- return wpa_driver_nl80211_set_freq(drv, freq->freq, freq->ht_enabled,
- freq->sec_channel_offset);
-}
-
-
-#ifdef HOSTAPD
static int i802_set_rts(void *priv, int rts)
{
@@ -5511,37 +5444,6 @@
}
-static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val,
- const char *bridge_ifname)
-{
- struct i802_bss *bss = priv;
- struct wpa_driver_nl80211_data *drv = bss->drv;
- char name[IFNAMSIZ + 1];
-
- os_snprintf(name, sizeof(name), "%s.sta%d", bss->ifname, aid);
- wpa_printf(MSG_DEBUG, "nl80211: Set WDS STA addr=" MACSTR
- " aid=%d val=%d name=%s", MAC2STR(addr), aid, val, name);
- if (val) {
- if (!if_nametoindex(name)) {
- if (nl80211_create_iface(drv, name,
- NL80211_IFTYPE_AP_VLAN,
- NULL, 1) < 0)
- return -1;
- if (bridge_ifname &&
- linux_br_add_if(drv->ioctl_sock, bridge_ifname,
- name) < 0)
- return -1;
- }
- linux_set_iface_flags(drv->ioctl_sock, name, 1);
- return i802_set_sta_vlan(priv, addr, name, 0);
- } else {
- i802_set_sta_vlan(priv, addr, bss->ifname, 0);
- return wpa_driver_nl80211_if_remove(priv, WPA_IF_AP_VLAN,
- name);
- }
-}
-
-
static int i802_set_ht_params(void *priv, const u8 *ht_capab,
size_t ht_capab_len, const u8 *ht_oper,
size_t ht_oper_len)
@@ -5555,26 +5457,6 @@
}
-static void handle_eapol(int sock, void *eloop_ctx, void *sock_ctx)
-{
- struct wpa_driver_nl80211_data *drv = eloop_ctx;
- struct sockaddr_ll lladdr;
- unsigned char buf[3000];
- int len;
- socklen_t fromlen = sizeof(lladdr);
-
- len = recvfrom(sock, buf, sizeof(buf), 0,
- (struct sockaddr *)&lladdr, &fromlen);
- if (len < 0) {
- perror("recv");
- return;
- }
-
- if (have_ifidx(drv, lladdr.sll_ifindex))
- drv_event_eapol_rx(drv->ctx, lladdr.sll_addr, buf, len);
-}
-
-
static int i802_get_inact_sec(void *priv, const u8 *addr)
{
struct hostap_sta_driver_data data;
@@ -5596,9 +5478,6 @@
return 0;
}
-#endif /* HOSTAPD */
-
-#if defined(HOSTAPD) || defined(CONFIG_AP)
static int i802_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
int reason)
@@ -5641,6 +5520,120 @@
#ifdef HOSTAPD
+static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
+{
+ int i;
+ int *old;
+
+ wpa_printf(MSG_DEBUG, "nl80211: Add own interface ifindex %d",
+ ifidx);
+ for (i = 0; i < drv->num_if_indices; i++) {
+ if (drv->if_indices[i] == 0) {
+ drv->if_indices[i] = ifidx;
+ return;
+ }
+ }
+
+ if (drv->if_indices != drv->default_if_indices)
+ old = drv->if_indices;
+ else
+ old = NULL;
+
+ drv->if_indices = os_realloc(old,
+ sizeof(int) * (drv->num_if_indices + 1));
+ if (!drv->if_indices) {
+ if (!old)
+ drv->if_indices = drv->default_if_indices;
+ else
+ drv->if_indices = old;
+ wpa_printf(MSG_ERROR, "Failed to reallocate memory for "
+ "interfaces");
+ wpa_printf(MSG_ERROR, "Ignoring EAPOL on interface %d", ifidx);
+ return;
+ } else if (!old)
+ os_memcpy(drv->if_indices, drv->default_if_indices,
+ sizeof(drv->default_if_indices));
+ drv->if_indices[drv->num_if_indices] = ifidx;
+ drv->num_if_indices++;
+}
+
+
+static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
+{
+ int i;
+
+ for (i = 0; i < drv->num_if_indices; i++) {
+ if (drv->if_indices[i] == ifidx) {
+ drv->if_indices[i] = 0;
+ break;
+ }
+ }
+}
+
+
+static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
+{
+ int i;
+
+ for (i = 0; i < drv->num_if_indices; i++)
+ if (drv->if_indices[i] == ifidx)
+ return 1;
+
+ return 0;
+}
+
+
+static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val,
+ const char *bridge_ifname)
+{
+ struct i802_bss *bss = priv;
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+ char name[IFNAMSIZ + 1];
+
+ os_snprintf(name, sizeof(name), "%s.sta%d", bss->ifname, aid);
+ wpa_printf(MSG_DEBUG, "nl80211: Set WDS STA addr=" MACSTR
+ " aid=%d val=%d name=%s", MAC2STR(addr), aid, val, name);
+ if (val) {
+ if (!if_nametoindex(name)) {
+ if (nl80211_create_iface(drv, name,
+ NL80211_IFTYPE_AP_VLAN,
+ NULL, 1) < 0)
+ return -1;
+ if (bridge_ifname &&
+ linux_br_add_if(drv->ioctl_sock, bridge_ifname,
+ name) < 0)
+ return -1;
+ }
+ linux_set_iface_flags(drv->ioctl_sock, name, 1);
+ return i802_set_sta_vlan(priv, addr, name, 0);
+ } else {
+ i802_set_sta_vlan(priv, addr, bss->ifname, 0);
+ return wpa_driver_nl80211_if_remove(priv, WPA_IF_AP_VLAN,
+ name);
+ }
+}
+
+
+static void handle_eapol(int sock, void *eloop_ctx, void *sock_ctx)
+{
+ struct wpa_driver_nl80211_data *drv = eloop_ctx;
+ struct sockaddr_ll lladdr;
+ unsigned char buf[3000];
+ int len;
+ socklen_t fromlen = sizeof(lladdr);
+
+ len = recvfrom(sock, buf, sizeof(buf), 0,
+ (struct sockaddr *)&lladdr, &fromlen);
+ if (len < 0) {
+ perror("recv");
+ return;
+ }
+
+ if (have_ifidx(drv, lladdr.sll_ifindex))
+ drv_event_eapol_rx(drv->ctx, lladdr.sll_addr, buf, len);
+}
+
+
static int i802_check_bridge(struct wpa_driver_nl80211_data *drv,
struct i802_bss *bss,
const char *brname, const char *ifname)
@@ -6562,6 +6555,55 @@
}
+static int nl80211_pmkid(struct i802_bss *bss, int cmd, const u8 *bssid,
+ const u8 *pmkid)
+{
+ struct nl_msg *msg;
+
+ msg = nlmsg_alloc();
+ if (!msg)
+ return -ENOMEM;
+
+ genlmsg_put(msg, 0, 0, genl_family_get_id(bss->drv->nl80211), 0, 0,
+ cmd, 0);
+
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
+ if (pmkid)
+ NLA_PUT(msg, NL80211_ATTR_PMKID, 16, pmkid);
+ if (bssid)
+ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
+
+ return send_and_recv_msgs(bss->drv, msg, NULL, NULL);
+ nla_put_failure:
+ return -ENOBUFS;
+}
+
+
+static int nl80211_add_pmkid(void *priv, const u8 *bssid, const u8 *pmkid)
+{
+ struct i802_bss *bss = priv;
+ wpa_printf(MSG_DEBUG, "nl80211: Add PMKID for " MACSTR, MAC2STR(bssid));
+ return nl80211_pmkid(bss, NL80211_CMD_SET_PMKSA, bssid, pmkid);
+}
+
+
+static int nl80211_remove_pmkid(void *priv, const u8 *bssid, const u8 *pmkid)
+{
+ struct i802_bss *bss = priv;
+ wpa_printf(MSG_DEBUG, "nl80211: Delete PMKID for " MACSTR,
+ MAC2STR(bssid));
+ return nl80211_pmkid(bss, NL80211_CMD_DEL_PMKSA, bssid, pmkid);
+}
+
+
+static int nl80211_flush_pmkid(void *priv)
+{
+ struct i802_bss *bss = priv;
+ wpa_printf(MSG_DEBUG, "nl80211: Flush PMKIDs");
+ return nl80211_pmkid(bss, NL80211_CMD_FLUSH_PMKSA, NULL, NULL);
+}
+
+
const struct wpa_driver_ops wpa_driver_nl80211_ops = {
.name = "nl80211",
.desc = "Linux nl80211/cfg80211",
@@ -6594,6 +6636,9 @@
#ifdef HOSTAPD
.hapd_init = i802_init,
.hapd_deinit = i802_deinit,
+ .set_wds_sta = i802_set_wds_sta,
+#endif /* HOSTAPD */
+#if defined(HOSTAPD) || defined(CONFIG_AP)
.get_seqnum = i802_get_seqnum,
.flush = i802_flush,
.read_sta_data = i802_read_sta_data,
@@ -6601,16 +6646,13 @@
.sta_clear_stats = i802_sta_clear_stats,
.set_rts = i802_set_rts,
.set_frag = i802_set_frag,
- .set_rate_sets = i802_set_rate_sets,
.set_cts_protect = i802_set_cts_protect,
.set_preamble = i802_set_preamble,
.set_short_slot_time = i802_set_short_slot_time,
.set_tx_queue_params = i802_set_tx_queue_params,
.set_sta_vlan = i802_set_sta_vlan,
- .set_wds_sta = i802_set_wds_sta,
.set_ht_params = i802_set_ht_params,
-#endif /* HOSTAPD */
-#if defined(HOSTAPD) || defined(CONFIG_AP)
+ .set_rate_sets = i802_set_rate_sets,
.sta_deauth = i802_sta_deauth,
.sta_disassoc = i802_sta_disassoc,
#endif /* HOSTAPD || CONFIG_AP */
@@ -6631,4 +6673,7 @@
.set_intra_bss = nl80211_set_intra_bss,
.set_param = nl80211_set_param,
.get_radio_name = nl80211_get_radio_name,
+ .add_pmkid = nl80211_add_pmkid,
+ .remove_pmkid = nl80211_remove_pmkid,
+ .flush_pmkid = nl80211_flush_pmkid,
};