Cumulative patch from commit 8615bdfac90174c3730ae5e6607b85f8bbec847e
8615bdf Increase global ctrl_iface buffer to same size as per-interface
c5a64e2 GAS client: Use Protected Dual of Public Action frames with PMF
5ce00d0 GAS server: Add support for Protected Dual of Public Action frames
e24fe94 Add definitions for Protected Dual of Public Action frames
7b2c42f hostapd: Fix PMF robust Action frame processing rules
ea6e040 Clear more configuration parameters to default on FLUSH
cf70d29 wpa_supplicant: Schedule PNO on completion of ongoing sched_scan
080cc44 nl80211: Fix sizeof check in vendor command/event handling
a487b35 hostapd: Fix segmentation fault when calling hostapd_cli all_sta
a6cff8b wpa_supplicant: Fix seg fault in wpas_ctrl_radio_work_flush() in error case
f62a3c2 P2P: Clone dtim_period to a new interface
88a0bca Update copyright years in the manpages
32185f5 Sync manpages and command-line options
b948e78 Add manpage for eapol_test
36bd29e wpa_supplicant: Fix usage text based on build options
dcdd383 P2P: Reduce peer expiration age to 60 sec and allow customization
dd27185 Skip normal scan when PNO is already in progress
a2d6365 P2P: Extend the listen time based on the active concurrent session
Change-Id: Iad81dc478319e59d8cfb673e2988d8bd3099b313
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c
index 3fb9e04..8c0cbab 100644
--- a/src/ap/ctrl_iface_ap.c
+++ b/src/ap/ctrl_iface_ap.c
@@ -86,6 +86,9 @@
{
int len, res, ret, i;
+ if (!sta)
+ return 0;
+
len = 0;
ret = os_snprintf(buf + len, buflen - len, MACSTR "\nflags=",
MAC2STR(sta->addr));
@@ -203,7 +206,11 @@
if (ret < 0 || (size_t) ret >= buflen)
return 0;
return ret;
- }
+ }
+
+ if (!sta->next)
+ return 0;
+
return hostapd_ctrl_iface_sta_mib(hapd, sta->next, buf, buflen);
}
diff --git a/src/ap/gas_serv.c b/src/ap/gas_serv.c
index 8349c4d..b5fb7df 100644
--- a/src/ap/gas_serv.c
+++ b/src/ap/gas_serv.c
@@ -1,6 +1,6 @@
/*
* Generic advertisement service (GAS) server
- * Copyright (c) 2011-2012, Qualcomm Atheros, Inc.
+ * Copyright (c) 2011-2014, Qualcomm Atheros, Inc.
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -19,6 +19,13 @@
#include "gas_serv.h"
+static void convert_to_protected_dual(struct wpabuf *msg)
+{
+ u8 *categ = wpabuf_mhead_u8(msg);
+ *categ = WLAN_ACTION_PROTECTED_DUAL;
+}
+
+
static struct gas_dialog_info *
gas_dialog_create(struct hostapd_data *hapd, const u8 *addr, u8 dialog_token)
{
@@ -774,7 +781,7 @@
static void gas_serv_req_local_processing(struct hostapd_data *hapd,
const u8 *sa, u8 dialog_token,
- struct anqp_query_info *qi)
+ struct anqp_query_info *qi, int prot)
{
struct wpabuf *buf, *tx_buf;
@@ -806,6 +813,7 @@
wpabuf_free(buf);
return;
}
+ di->prot = prot;
di->sd_resp = buf;
di->sd_resp_pos = 0;
tx_buf = gas_anqp_build_initial_resp_buf(
@@ -819,7 +827,8 @@
}
if (!tx_buf)
return;
-
+ if (prot)
+ convert_to_protected_dual(tx_buf);
hostapd_drv_send_action(hapd, hapd->iface->freq, 0, sa,
wpabuf_head(tx_buf), wpabuf_len(tx_buf));
wpabuf_free(tx_buf);
@@ -828,7 +837,7 @@
static void gas_serv_rx_gas_initial_req(struct hostapd_data *hapd,
const u8 *sa,
- const u8 *data, size_t len)
+ const u8 *data, size_t len, int prot)
{
const u8 *pos = data;
const u8 *end = data + len;
@@ -878,6 +887,8 @@
return;
wpabuf_put_data(buf, adv_proto, 2 + slen);
wpabuf_put_le16(buf, 0); /* Query Response Length */
+ if (prot)
+ convert_to_protected_dual(buf);
hostapd_drv_send_action(hapd, hapd->iface->freq, 0, sa,
wpabuf_head(buf), wpabuf_len(buf));
wpabuf_free(buf);
@@ -929,7 +940,7 @@
pos += elen;
}
- gas_serv_req_local_processing(hapd, sa, dialog_token, &qi);
+ gas_serv_req_local_processing(hapd, sa, dialog_token, &qi, prot);
}
@@ -975,6 +986,8 @@
if (tx_buf) {
wpa_msg(hapd->msg_ctx, MSG_DEBUG,
"GAS: Tx GAS Initial Resp (comeback = 10TU)");
+ if (dialog->prot)
+ convert_to_protected_dual(tx_buf);
hostapd_drv_send_action(hapd, hapd->iface->freq, 0,
dst,
wpabuf_head(tx_buf),
@@ -1012,6 +1025,8 @@
dialog->sd_frag_id, (int) frag_len);
dialog->sd_frag_id++;
+ if (dialog->prot)
+ convert_to_protected_dual(tx_buf);
hostapd_drv_send_action(hapd, hapd->iface->freq, 0, dst,
wpabuf_head(tx_buf), wpabuf_len(tx_buf));
wpabuf_free(tx_buf);
@@ -1022,7 +1037,7 @@
static void gas_serv_rx_gas_comeback_req(struct hostapd_data *hapd,
const u8 *sa,
- const u8 *data, size_t len)
+ const u8 *data, size_t len, int prot)
{
struct gas_dialog_info *dialog;
struct wpabuf *buf, *tx_buf;
@@ -1120,6 +1135,8 @@
}
send_resp:
+ if (prot)
+ convert_to_protected_dual(tx_buf);
hostapd_drv_send_action(hapd, hapd->iface->freq, 0, sa,
wpabuf_head(tx_buf), wpabuf_len(tx_buf));
wpabuf_free(tx_buf);
@@ -1137,22 +1154,30 @@
const struct ieee80211_mgmt *mgmt;
size_t hdr_len;
const u8 *sa, *data;
+ int prot;
mgmt = (const struct ieee80211_mgmt *) buf;
hdr_len = (const u8 *) &mgmt->u.action.u.vs_public_action.action - buf;
if (hdr_len > len)
return;
- if (mgmt->u.action.category != WLAN_ACTION_PUBLIC)
+ if (mgmt->u.action.category != WLAN_ACTION_PUBLIC &&
+ mgmt->u.action.category != WLAN_ACTION_PROTECTED_DUAL)
return;
+ /*
+ * Note: Public Action and Protected Dual of Public Action frames share
+ * the same payload structure, so it is fine to use definitions of
+ * Public Action frames to process both.
+ */
+ prot = mgmt->u.action.category == WLAN_ACTION_PROTECTED_DUAL;
sa = mgmt->sa;
len -= hdr_len;
data = &mgmt->u.action.u.public_action.action;
switch (data[0]) {
case WLAN_PA_GAS_INITIAL_REQ:
- gas_serv_rx_gas_initial_req(hapd, sa, data + 1, len - 1);
+ gas_serv_rx_gas_initial_req(hapd, sa, data + 1, len - 1, prot);
break;
case WLAN_PA_GAS_COMEBACK_REQ:
- gas_serv_rx_gas_comeback_req(hapd, sa, data + 1, len - 1);
+ gas_serv_rx_gas_comeback_req(hapd, sa, data + 1, len - 1, prot);
break;
}
}
diff --git a/src/ap/gas_serv.h b/src/ap/gas_serv.h
index 4213cf6..74739fe 100644
--- a/src/ap/gas_serv.h
+++ b/src/ap/gas_serv.h
@@ -50,6 +50,7 @@
size_t sd_resp_pos; /* Offset in sd_resp */
u8 sd_frag_id;
u16 comeback_delay;
+ int prot; /* whether Protected Dual of Public Action frame is used */
unsigned int requested;
unsigned int received;
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 1e3693d..dee3c7a 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -1588,8 +1588,8 @@
#ifdef CONFIG_IEEE80211W
if (sta && (sta->flags & WLAN_STA_MFP) &&
- !(mgmt->frame_control & host_to_le16(WLAN_FC_ISWEP) &&
- robust_action_frame(mgmt->u.action.category))) {
+ !(mgmt->frame_control & host_to_le16(WLAN_FC_ISWEP)) &&
+ robust_action_frame(mgmt->u.action.category)) {
hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_DEBUG,
"Dropped unprotected Robust Action frame from "
@@ -1619,6 +1619,7 @@
return 1;
#endif /* CONFIG_WNM */
case WLAN_ACTION_PUBLIC:
+ case WLAN_ACTION_PROTECTED_DUAL:
if (hapd->public_action_cb) {
hapd->public_action_cb(hapd->public_action_cb_ctx,
(u8 *) mgmt, len,
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index 12dc83e..592ae54 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -271,6 +271,7 @@
#define WLAN_ACTION_FT 6
#define WLAN_ACTION_HT 7
#define WLAN_ACTION_SA_QUERY 8
+#define WLAN_ACTION_PROTECTED_DUAL 9
#define WLAN_ACTION_WNM 10
#define WLAN_ACTION_UNPROTECTED_WNM 11
#define WLAN_ACTION_TDLS 12
@@ -286,6 +287,19 @@
#define WLAN_PA_GAS_COMEBACK_RESP 13
#define WLAN_TDLS_DISCOVERY_RESPONSE 14
+/* Protected Dual of Public Action frames */
+#define WLAN_PROT_DSE_ENABLEMENT 1
+#define WLAN_PROT_DSE_DEENABLEMENT 2
+#define WLAN_PROT_EXT_CSA 4
+#define WLAN_PROT_MEASUREMENT_REQ 5
+#define WLAN_PROT_MEASUREMENT_REPORT 6
+#define WLAN_PROT_DSE_POWER_CONSTRAINT 8
+#define WLAN_PROT_VENDOR_SPECIFIC 9
+#define WLAN_PROT_GAS_INITIAL_REQ 10
+#define WLAN_PROT_GAS_INITIAL_RESP 11
+#define WLAN_PROT_GAS_COMEBACK_REQ 12
+#define WLAN_PROT_GAS_COMEBACK_RESP 13
+
/* SA Query Action frame (IEEE 802.11w/D8.0, 7.4.9) */
#define WLAN_SA_QUERY_REQUEST 0
#define WLAN_SA_QUERY_RESPONSE 1
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 0b8eed5..b5bf368 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -3584,7 +3584,7 @@
nla_for_each_nested(nl, tb[NL80211_ATTR_VENDOR_DATA], rem) {
struct nl80211_vendor_cmd_info *vinfo;
- if (nla_len(nl) != sizeof(vinfo)) {
+ if (nla_len(nl) != sizeof(*vinfo)) {
wpa_printf(MSG_DEBUG, "nl80211: Unexpected vendor data info");
continue;
}
@@ -3600,7 +3600,7 @@
nla_for_each_nested(nl, tb[NL80211_ATTR_VENDOR_EVENTS], rem) {
struct nl80211_vendor_cmd_info *vinfo;
- if (nla_len(nl) != sizeof(vinfo)) {
+ if (nla_len(nl) != sizeof(*vinfo)) {
wpa_printf(MSG_DEBUG, "nl80211: Unexpected vendor data info");
continue;
}
@@ -4216,6 +4216,18 @@
/* GAS Comeback Response */
if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0d", 2) < 0)
ret = -1;
+ /* Protected GAS Initial Request */
+ if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0a", 2) < 0)
+ ret = -1;
+ /* Protected GAS Initial Response */
+ if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0b", 2) < 0)
+ ret = -1;
+ /* Protected GAS Comeback Request */
+ if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0c", 2) < 0)
+ ret = -1;
+ /* Protected GAS Comeback Response */
+ if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0d", 2) < 0)
+ ret = -1;
#endif /* CONFIG_P2P || CONFIG_INTERWORKING */
#ifdef CONFIG_P2P
/* P2P Public Action */
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index f2aa971..8aabfc0 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -43,7 +43,7 @@
*/
#ifndef P2P_PEER_EXPIRATION_AGE
#define P2P_PEER_EXPIRATION_AGE 60
-#endif
+#endif /* P2P_PEER_EXPIRATION_AGE */
#define P2P_PEER_EXPIRATION_INTERVAL (P2P_PEER_EXPIRATION_AGE / 2)
@@ -3151,13 +3151,13 @@
static void p2p_timeout_wait_peer_connect(struct p2p_data *p2p)
{
- /*
- * TODO: could remain constantly in Listen state for some time if there
- * are no other concurrent uses for the radio. For now, go to listen
- * state once per second to give other uses a chance to use the radio.
- */
p2p_set_state(p2p, P2P_WAIT_PEER_IDLE);
- p2p_set_timeout(p2p, 0, 500000);
+
+ if (p2p->cfg->is_concurrent_session_active &&
+ p2p->cfg->is_concurrent_session_active(p2p->cfg->cb_ctx))
+ p2p_set_timeout(p2p, 0, 500000);
+ else
+ p2p_set_timeout(p2p, 0, 200000);
}
diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h
index 25a91e7..2ce6ea6 100644
--- a/src/p2p/p2p.h
+++ b/src/p2p/p2p.h
@@ -789,6 +789,15 @@
*/
void (*presence_resp)(void *ctx, const u8 *src, u8 status,
const u8 *noa, size_t noa_len);
+
+ /**
+ * is_concurrent_session_active - Check whether concurrent session is
+ * active on other virtual interfaces
+ * @ctx: Callback context from cb_ctx
+ * Returns: 1 if concurrent session is active on other virtual interface
+ * or 0 if not.
+ */
+ int (*is_concurrent_session_active)(void *ctx);
};
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index ea4e6bb..5f69389 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -360,6 +360,8 @@
hdr_len = (const u8 *) &mgmt->u.action.u.vs_public_action.action - buf;
if (hdr_len > len)
return;
+ if (mgmt->u.action.category != WLAN_ACTION_PUBLIC)
+ return;
wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid,
mgmt->u.action.category,
&mgmt->u.action.u.vs_public_action.action,
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index f7ee6e3..68157d2 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -54,7 +54,7 @@
struct wpa_ssid *ssid;
struct wpa_driver_scan_params params;
- if (wpa_s->pno)
+ if (wpa_s->pno || wpa_s->pno_sched_pending)
return 0;
if ((wpa_s->wpa_state > WPA_SCANNING) &&
@@ -64,8 +64,14 @@
}
if (wpa_s->wpa_state == WPA_SCANNING) {
- wpa_supplicant_cancel_sched_scan(wpa_s);
wpa_supplicant_cancel_scan(wpa_s);
+ if (wpa_s->sched_scanning) {
+ wpa_printf(MSG_DEBUG, "Schedule PNO on completion of "
+ "ongoing sched scan");
+ wpa_supplicant_cancel_sched_scan(wpa_s);
+ wpa_s->pno_sched_pending = 1;
+ return 0;
+ }
}
os_memset(¶ms, 0, sizeof(params));
@@ -128,11 +134,13 @@
{
int ret = 0;
- if (wpa_s->pno) {
+ if (wpa_s->pno || wpa_s->sched_scanning) {
wpa_s->pno = 0;
ret = wpa_supplicant_stop_sched_scan(wpa_s);
}
+ wpa_s->pno_sched_pending = 0;
+
if (wpa_s->wpa_state == WPA_SCANNING)
wpa_supplicant_req_scan(wpa_s, 0, 0);
@@ -5307,6 +5315,9 @@
wpa_supplicant_ctrl_iface_remove_network(wpa_s, "all");
wpa_supplicant_ctrl_iface_remove_cred(wpa_s, "all");
wpa_config_flush_blobs(wpa_s->conf);
+ wpa_s->conf->auto_interworking = 0;
+ wpa_s->conf->okc = 0;
+ wpa_s->conf->pmf = 0;
wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME, 43200);
wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD, 70);
@@ -5477,6 +5488,9 @@
{
struct wpa_radio_work *work, *tmp;
+ if (!wpa_s || !wpa_s->radio)
+ return;
+
dl_list_for_each_safe(work, tmp, &wpa_s->radio->work,
struct wpa_radio_work, list) {
struct wpa_external_work *ework;
diff --git a/wpa_supplicant/ctrl_iface_unix.c b/wpa_supplicant/ctrl_iface_unix.c
index 8fb217d..d44313c 100644
--- a/wpa_supplicant/ctrl_iface_unix.c
+++ b/wpa_supplicant/ctrl_iface_unix.c
@@ -800,7 +800,7 @@
{
struct wpa_global *global = eloop_ctx;
struct ctrl_iface_global_priv *priv = sock_ctx;
- char buf[256];
+ char buf[4096];
int res;
struct sockaddr_un from;
socklen_t fromlen = sizeof(from);
diff --git a/wpa_supplicant/doc/docbook/Makefile b/wpa_supplicant/doc/docbook/Makefile
index aaeee2e..82f9de3 100644
--- a/wpa_supplicant/doc/docbook/Makefile
+++ b/wpa_supplicant/doc/docbook/Makefile
@@ -7,6 +7,7 @@
FILES += wpa_priv
FILES += wpa_supplicant.conf
FILES += wpa_supplicant
+FILES += eapol_test
man:
for i in $(FILES); do docbook2man $$i.sgml; done
@@ -20,7 +21,7 @@
clean:
- rm -f wpa_background.8 wpa_cli.8 wpa_gui.8 wpa_passphrase.8 wpa_priv.8 wpa_supplicant.8
+ rm -f wpa_background.8 wpa_cli.8 wpa_gui.8 wpa_passphrase.8 wpa_priv.8 wpa_supplicant.8 eapol_test.8
rm -f wpa_supplicant.conf.5
rm -f manpage.links manpage.refs
rm -f $(FILES:%=%.pdf)
diff --git a/wpa_supplicant/doc/docbook/eapol_test.sgml b/wpa_supplicant/doc/docbook/eapol_test.sgml
new file mode 100644
index 0000000..fec174b
--- /dev/null
+++ b/wpa_supplicant/doc/docbook/eapol_test.sgml
@@ -0,0 +1,205 @@
+<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+
+<refentry>
+ <refmeta>
+ <refentrytitle>eapol_test</refentrytitle>
+ <manvolnum>8</manvolnum>
+ </refmeta>
+ <refnamediv>
+ <refname>eapol_test</refname>
+
+ <refpurpose>EAP peer and RADIUS client testing</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>eapol_test</command>
+ <arg>-nWS</arg>
+ <arg>-c<replaceable>config file</replaceable></arg>
+ <arg>-a<replaceable>server IP address</replaceable></arg>
+ <arg>-A<replaceable>client IP address</replaceable></arg>
+ <arg>-p<replaceable>UDP port</replaceable></arg>
+ <arg>-s<replaceable>shared secret</replaceable></arg>
+ <arg>-r<replaceable>re-authentications</replaceable></arg>
+ <arg>-t<replaceable>timeout</replaceable></arg>
+ <arg>-C<replaceable>Connect-Info</replaceable></arg>
+ <arg>-M<replaceable>MAC address</replaceable></arg>
+ <arg>-o<replaceable>file</replaceable></arg>
+ <arg>-N<replaceable>attr spec</replaceable></arg>
+ </cmdsynopsis>
+ <cmdsynopsis>
+ <command>eapol_test scard</command>
+ </cmdsynopsis>
+ <cmdsynopsis>
+ <command>eapol_test sim</command>
+ <arg>PIN</arg>
+ <arg>num triplets</arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Overview</title>
+
+ <para>eapol_test is a program that links together the same EAP
+ peer implementation that wpa_supplicant is using and the RADIUS
+ authentication client code from hostapd. In addition, it has
+ minimal glue code to combine these two components in similar
+ ways to IEEE 802.1X/EAPOL Authenticator state machines. In other
+ words, it integrates IEEE 802.1X Authenticator (normally, an
+ access point) and IEEE 802.1X Supplicant (normally, a wireless
+ client) together to generate a single program that can be used to
+ test EAP methods without having to setup an access point and a
+ wireless client.</para>
+
+ <para>The main uses for eapol_test are in interoperability testing
+ of EAP methods against RADIUS servers and in development testing
+ for new EAP methods. It can be easily used to automate EAP testing
+ for interoperability and regression since the program can be run
+ from shell scripts without require additional test components apart
+ from a RADIUS server. For example, the automated EAP tests described
+ in eap_testing.txt are implemented with eapol_test. Similarly,
+ eapol_test could be used to implement an automated regression
+ test suite for a RADIUS authentication server.</para>
+
+
+ <para>As an example:</para>
+
+<blockquote><programlisting>
+eapol_test -ctest.conf -a127.0.0.1 -p1812 -ssecret -r1
+</programlisting></blockquote>
+
+ <para>tries to complete EAP authentication based on the network
+ configuration from test.conf against the RADIUS server running
+ on the local host. A re-authentication is triggered to test fast
+ re-authentication. The configuration file uses the same format for
+ network blocks as wpa_supplicant.</para>
+
+ </refsect1>
+ <refsect1>
+ <title>Command Arguments</title>
+ <variablelist>
+ <varlistentry>
+ <term>-c configuration file path</term>
+
+ <listitem><para>A configuration to use. The configuration should
+ use the same format for network blocks as wpa_supplicant.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-a AS address</term>
+
+ <listitem><para>IP address of the authentication server. The
+ default is '127.0.0.1'.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-A client address</term>
+
+ <listitem><para>IP address of the client. The default is to
+ select an address automatically.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-p AS port</term>
+
+ <listitem><para>UDP port of the authentication server. The
+ default is '1812'.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-s AS secret</term>
+
+ <listitem><para>Shared secret with the authentication server.
+ The default is 'radius'.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-r count</term>
+
+ <listitem><para>Number of reauthentications.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-t timeout</term>
+
+ <listitem><para>Timeout in seconds. The default is 30.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-C info</term>
+
+ <listitem><para>RADIUS Connect-Info. The default is
+ 'CONNECT 11Mbps 802.11b'.</para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-M mac address</term>
+
+ <listitem><para>Client MAC address (Calling-Station-Id). The
+ default is '02:00:00:00:00:01'.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-o file</term>
+
+ <listitem><para>Location to write out server certificate.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-N attr spec</term>
+
+ <listitem><para>Send arbitrary attribute specific by
+ attr_id:syntax:value, or attr_id alone. attr_id should be the numeric
+ ID of the attribute, and syntax should be one of 's' (string),
+ 'd' (integer), or 'x' (octet string). The value is the attribute value
+ to send. When attr_id is given alone, NULL is used as the attribute
+ value. Multiple attributes can be specified by using the option
+ several times.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-n</term>
+
+ <listitem><para>Indicates that no MPPE keys are expected.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-W</term>
+
+ <listitem><para>Wait for a control interface monitor before starting.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-S</term>
+
+ <listitem><para>Save configuration after authentication.
+ </para></listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>See Also</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>wpa_supplicant</refentrytitle>
+ <manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Legal</title>
+ <para>wpa_supplicant is copyright (c) 2003-2014,
+ Jouni Malinen <email>j@w1.fi</email> and
+ contributors.
+ All Rights Reserved.</para>
+
+ <para>This program is licensed under the BSD license (the one with
+ advertisement clause removed).</para>
+ </refsect1>
+</refentry>
diff --git a/wpa_supplicant/doc/docbook/wpa_background.sgml b/wpa_supplicant/doc/docbook/wpa_background.sgml
index eb3a089..860b5a0 100644
--- a/wpa_supplicant/doc/docbook/wpa_background.sgml
+++ b/wpa_supplicant/doc/docbook/wpa_background.sgml
@@ -90,7 +90,7 @@
<refsect1>
<title>Legal</title>
- <para>wpa_supplicant is copyright (c) 2003-2012,
+ <para>wpa_supplicant is copyright (c) 2003-2014,
Jouni Malinen <email>j@w1.fi</email> and
contributors.
All Rights Reserved.</para>
diff --git a/wpa_supplicant/doc/docbook/wpa_cli.sgml b/wpa_supplicant/doc/docbook/wpa_cli.sgml
index c080c07..142e1ab 100644
--- a/wpa_supplicant/doc/docbook/wpa_cli.sgml
+++ b/wpa_supplicant/doc/docbook/wpa_cli.sgml
@@ -15,10 +15,12 @@
<cmdsynopsis>
<command>wpa_cli</command>
<arg>-p <replaceable>path to ctrl sockets</replaceable></arg>
+ <arg>-g <replaceable>path to global ctrl_interface socket</replaceable></arg>
<arg>-i <replaceable>ifname</replaceable></arg>
<arg>-hvB</arg>
<arg>-a <replaceable>action file</replaceable></arg>
<arg>-P <replaceable>pid file</replaceable></arg>
+ <arg>-G <replaceable>ping interval</replaceable></arg>
<arg><replaceable>command ...</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -111,6 +113,14 @@
</varlistentry>
<varlistentry>
+ <term>-g control socket path</term>
+
+ <listitem><para>Connect to the global control socket at the
+ indicated path rather than an interface-specific control
+ socket.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-i ifname</term>
<listitem><para>Specify the interface that is being
@@ -161,6 +171,13 @@
</varlistentry>
<varlistentry>
+ <term>-G ping interval</term>
+
+ <listitem><para>Set the interval (in seconds) at which
+ wpa_cli pings the supplicant.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>command</term>
<listitem><para>Run a command. The available commands are
@@ -328,7 +345,7 @@
</refsect1>
<refsect1>
<title>Legal</title>
- <para>wpa_supplicant is copyright (c) 2003-2012,
+ <para>wpa_supplicant is copyright (c) 2003-2014,
Jouni Malinen <email>j@w1.fi</email> and
contributors.
All Rights Reserved.</para>
diff --git a/wpa_supplicant/doc/docbook/wpa_gui.sgml b/wpa_supplicant/doc/docbook/wpa_gui.sgml
index 0ab6419..f6ef8f1 100644
--- a/wpa_supplicant/doc/docbook/wpa_gui.sgml
+++ b/wpa_supplicant/doc/docbook/wpa_gui.sgml
@@ -74,7 +74,7 @@
</refsect1>
<refsect1>
<title>Legal</title>
- <para>wpa_supplicant is copyright (c) 2003-2012,
+ <para>wpa_supplicant is copyright (c) 2003-2014,
Jouni Malinen <email>j@w1.fi</email> and
contributors.
All Rights Reserved.</para>
diff --git a/wpa_supplicant/doc/docbook/wpa_passphrase.sgml b/wpa_supplicant/doc/docbook/wpa_passphrase.sgml
index 336c03b..3b4360b 100644
--- a/wpa_supplicant/doc/docbook/wpa_passphrase.sgml
+++ b/wpa_supplicant/doc/docbook/wpa_passphrase.sgml
@@ -62,7 +62,7 @@
</refsect1>
<refsect1>
<title>Legal</title>
- <para>wpa_supplicant is copyright (c) 2003-2012,
+ <para>wpa_supplicant is copyright (c) 2003-2014,
Jouni Malinen <email>j@w1.fi</email> and
contributors.
All Rights Reserved.</para>
diff --git a/wpa_supplicant/doc/docbook/wpa_priv.sgml b/wpa_supplicant/doc/docbook/wpa_priv.sgml
index eb907a8..9c114cc 100644
--- a/wpa_supplicant/doc/docbook/wpa_priv.sgml
+++ b/wpa_supplicant/doc/docbook/wpa_priv.sgml
@@ -137,7 +137,7 @@
</refsect1>
<refsect1>
<title>Legal</title>
- <para>wpa_supplicant is copyright (c) 2003-2012,
+ <para>wpa_supplicant is copyright (c) 2003-2014,
Jouni Malinen <email>j@w1.fi</email> and
contributors.
All Rights Reserved.</para>
diff --git a/wpa_supplicant/doc/docbook/wpa_supplicant.sgml b/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
index aa20e57..182060d 100644
--- a/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
+++ b/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
@@ -12,7 +12,7 @@
<refsynopsisdiv>
<cmdsynopsis>
<command>wpa_supplicant</command>
- <arg>-BddfhKLqqtuvW</arg>
+ <arg>-BddfhKLqqsTtuvW</arg>
<arg>-i<replaceable>ifname</replaceable></arg>
<arg>-c<replaceable>config file</replaceable></arg>
<arg>-D<replaceable>driver</replaceable></arg>
@@ -344,9 +344,20 @@
</varlistentry>
<varlistentry>
+ <term>-e entropy file</term>
+ <listitem>
+ <para>File for <command>wpa_supplicant</command> to use to
+ maintain its internal entropy store in over restarts.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-f output file</term>
<listitem>
- <para>Log output to specified file instead of stdout.</para>
+ <para>Log output to specified file instead of stdout. (This
+ is only available if <command>wpa_supplicant</command> was
+ built with the <literal>CONFIG_DEBUG_FILE</literal>
+ option.)</para>
</listitem>
</varlistentry>
@@ -387,6 +398,22 @@
</varlistentry>
<varlistentry>
+ <term>-o override driver</term>
+ <listitem>
+ <para>Override the driver parameter for new
+ interfaces.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-O override ctrl_interface</term>
+ <listitem>
+ <para>Override the ctrl_interface parameter for new
+ interfaces.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-p</term>
<listitem>
<para>Driver parameters. (Per interface)</para>
@@ -409,10 +436,40 @@
</varlistentry>
<varlistentry>
+ <term>-s</term>
+ <listitem>
+ <para>Log output to syslog instead of stdout. (This is only
+ available if <command>wpa_supplicant</command> was built
+ with the <literal>CONFIG_DEBUG_SYSLOG</literal>
+ option.)</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-T</term>
+ <listitem>
+ <para>Log output to Linux tracing in addition to any other
+ destinations. (This is only available
+ if <command>wpa_supplicant</command> was built with
+ the <literal>CONFIG_DEBUG_LINUX_TRACING</literal>
+ option.)</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-t</term>
+ <listitem>
+ <para>Include timestamp in debug messages.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-u</term>
<listitem>
- <para>Enabled DBus control interface. If enabled, interface
- definitions may be omitted.</para>
+ <para>Enable DBus control interface. If enabled, interface
+ definitions may be omitted. (This is only available
+ if <command>wpa_supplicant</command> was built with
+ the <literal>CONFIG_DBUS</literal> option.)</para>0
</listitem>
</varlistentry>
@@ -679,7 +736,7 @@
</refsect1>
<refsect1>
<title>Legal</title>
- <para>wpa_supplicant is copyright (c) 2003-2012,
+ <para>wpa_supplicant is copyright (c) 2003-2014,
Jouni Malinen <email>j@w1.fi</email> and
contributors.
All Rights Reserved.</para>
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index f5834d4..72d2d5b 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -2739,8 +2739,10 @@
#endif /* CONFIG_WNM */
#ifdef CONFIG_GAS
- if (mgmt->u.action.category == WLAN_ACTION_PUBLIC &&
+ if ((mgmt->u.action.category == WLAN_ACTION_PUBLIC ||
+ mgmt->u.action.category == WLAN_ACTION_PROTECTED_DUAL) &&
gas_query_rx(wpa_s->gas, mgmt->da, mgmt->sa, mgmt->bssid,
+ mgmt->u.action.category,
payload, plen, freq) == 0)
return;
#endif /* CONFIG_GAS */
@@ -3240,6 +3242,7 @@
data->driver_gtk_rekey.replay_ctr);
break;
case EVENT_SCHED_SCAN_STOPPED:
+ wpa_s->pno = 0;
wpa_s->sched_scanning = 0;
wpa_supplicant_notify_scanning(wpa_s, 0);
@@ -3247,11 +3250,20 @@
break;
/*
- * If we timed out, start a new sched scan to continue
- * searching for more SSIDs.
+ * Start a new sched scan to continue searching for more SSIDs
+ * either if timed out or PNO schedule scan is pending.
*/
- if (wpa_s->sched_scan_timed_out)
- wpa_supplicant_req_sched_scan(wpa_s);
+ if (wpa_s->sched_scan_timed_out || wpa_s->pno_sched_pending) {
+
+ if (wpa_supplicant_req_sched_scan(wpa_s) < 0 &&
+ wpa_s->pno_sched_pending) {
+ wpa_msg(wpa_s, MSG_ERROR, "Failed to schedule PNO");
+ } else if (wpa_s->pno_sched_pending) {
+ wpa_s->pno_sched_pending = 0;
+ wpa_s->pno = 1;
+ }
+ }
+
break;
case EVENT_WPS_BUTTON_PUSHED:
#ifdef CONFIG_WPS
diff --git a/wpa_supplicant/gas_query.c b/wpa_supplicant/gas_query.c
index f002fd5..abcb391 100644
--- a/wpa_supplicant/gas_query.c
+++ b/wpa_supplicant/gas_query.c
@@ -1,7 +1,7 @@
/*
* Generic advertisement service (GAS) query
* Copyright (c) 2009, Atheros Communications
- * Copyright (c) 2011-2013, Qualcomm Atheros, Inc.
+ * Copyright (c) 2011-2014, Qualcomm Atheros, Inc.
* Copyright (c) 2011-2014, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
@@ -15,6 +15,7 @@
#include "common/ieee802_11_defs.h"
#include "common/gas.h"
#include "common/wpa_ctrl.h"
+#include "rsn_supp/wpa.h"
#include "wpa_supplicant_i.h"
#include "driver_i.h"
#include "offchannel.h"
@@ -228,13 +229,28 @@
}
+static int pmf_in_use(struct wpa_supplicant *wpa_s, const u8 *addr)
+{
+ if (wpa_s->current_ssid == NULL ||
+ wpa_s->wpa_state < WPA_4WAY_HANDSHAKE ||
+ os_memcmp(addr, wpa_s->bssid, ETH_ALEN) != 0)
+ return 0;
+ return wpa_sm_pmf_enabled(wpa_s->wpa);
+}
+
+
static int gas_query_tx(struct gas_query *gas, struct gas_query_pending *query,
struct wpabuf *req)
{
- int res;
+ int res, prot = pmf_in_use(gas->wpa_s, query->addr);
+
wpa_printf(MSG_DEBUG, "GAS: Send action frame to " MACSTR " len=%u "
- "freq=%d", MAC2STR(query->addr),
- (unsigned int) wpabuf_len(req), query->freq);
+ "freq=%d prot=%d", MAC2STR(query->addr),
+ (unsigned int) wpabuf_len(req), query->freq, prot);
+ if (prot) {
+ u8 *categ = wpabuf_mhead_u8(req);
+ *categ = WLAN_ACTION_PROTECTED_DUAL;
+ }
res = offchannel_send_action(gas->wpa_s, query->freq, query->addr,
gas->wpa_s->own_addr, query->addr,
wpabuf_head(req), wpabuf_len(req), 1000,
@@ -386,27 +402,41 @@
/**
- * gas_query_rx - Indicate reception of a Public Action frame
+ * gas_query_rx - Indicate reception of a Public Action or Protected Dual frame
* @gas: GAS query data from gas_query_init()
* @da: Destination MAC address of the Action frame
* @sa: Source MAC address of the Action frame
* @bssid: BSSID of the Action frame
+ * @categ: Category of the Action frame
* @data: Payload of the Action frame
* @len: Length of @data
* @freq: Frequency (in MHz) on which the frame was received
* Returns: 0 if the Public Action frame was a GAS frame or -1 if not
*/
int gas_query_rx(struct gas_query *gas, const u8 *da, const u8 *sa,
- const u8 *bssid, const u8 *data, size_t len, int freq)
+ const u8 *bssid, u8 categ, const u8 *data, size_t len,
+ int freq)
{
struct gas_query_pending *query;
u8 action, dialog_token, frag_id = 0, more_frags = 0;
u16 comeback_delay, resp_len;
const u8 *pos, *adv_proto;
+ int prot, pmf;
if (gas == NULL || len < 4)
return -1;
+ prot = categ == WLAN_ACTION_PROTECTED_DUAL;
+ pmf = pmf_in_use(gas->wpa_s, bssid);
+ if (prot && !pmf) {
+ wpa_printf(MSG_DEBUG, "GAS: Drop unexpected protected GAS frame when PMF is disabled");
+ return 0;
+ }
+ if (!prot && pmf) {
+ wpa_printf(MSG_DEBUG, "GAS: Drop unexpected unprotected GAS frame when PMF is enabled");
+ return 0;
+ }
+
pos = data;
action = *pos++;
dialog_token = *pos++;
diff --git a/wpa_supplicant/gas_query.h b/wpa_supplicant/gas_query.h
index 5c3d161..ad13490 100644
--- a/wpa_supplicant/gas_query.h
+++ b/wpa_supplicant/gas_query.h
@@ -17,7 +17,8 @@
struct gas_query * gas_query_init(struct wpa_supplicant *wpa_s);
void gas_query_deinit(struct gas_query *gas);
int gas_query_rx(struct gas_query *gas, const u8 *da, const u8 *sa,
- const u8 *bssid, const u8 *data, size_t len, int freq);
+ const u8 *bssid, u8 categ, const u8 *data, size_t len,
+ int freq);
/**
* enum gas_query_result - GAS query result
diff --git a/wpa_supplicant/main.c b/wpa_supplicant/main.c
index 37f0c78..d56935d 100644
--- a/wpa_supplicant/main.c
+++ b/wpa_supplicant/main.c
@@ -22,13 +22,24 @@
int i;
printf("%s\n\n%s\n"
"usage:\n"
- " wpa_supplicant [-BddhKLqqstuvW] [-P<pid file>] "
+ " wpa_supplicant [-BddhKLqq"
+#ifdef CONFIG_DEBUG_SYSLOG
+ "s"
+#endif /* CONFIG_DEBUG_SYSLOG */
+ "t"
+#ifdef CONFIG_DBUS
+ "u"
+#endif /* CONFIG_DBUS */
+ "vW] [-P<pid file>] "
"[-g<global ctrl>] \\\n"
" [-G<group>] \\\n"
" -i<ifname> -c<config file> [-C<ctrl>] [-D<driver>] "
"[-p<driver_param>] \\\n"
- " [-b<br_ifname>] [-f<debug file>] [-e<entropy file>] "
- "\\\n"
+ " [-b<br_ifname>] [-e<entropy file>]"
+#ifdef CONFIG_DEBUG_FILE
+ " [-f<debug file>]"
+#endif /* CONFIG_DEBUG_FILE */
+ " \\\n"
" [-o<override driver>] [-O<override ctrl>] \\\n"
" [-N -i<ifname> -c<conf> [-C<ctrl>] "
"[-D<driver>] \\\n"
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 91ed508..889a949 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -1342,6 +1342,7 @@
d->pbc_in_m1 = s->pbc_in_m1;
d->ignore_old_scan_res = s->ignore_old_scan_res;
d->beacon_int = s->beacon_int;
+ d->dtim_period = s->dtim_period;
d->disassoc_low_ack = s->disassoc_low_ack;
d->disable_scan_offload = s->disable_scan_offload;
}
@@ -3571,6 +3572,21 @@
}
+static int wpas_is_concurrent_session_active(void *ctx)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+ struct wpa_supplicant *ifs;
+
+ for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
+ if (ifs == wpa_s)
+ continue;
+ if (ifs->wpa_state > WPA_ASSOCIATED)
+ return 1;
+ }
+ return 0;
+}
+
+
static void wpas_p2p_debug_print(void *ctx, int level, const char *msg)
{
struct wpa_supplicant *wpa_s = ctx;
@@ -3685,6 +3701,7 @@
p2p.get_noa = wpas_get_noa;
p2p.go_connected = wpas_go_connected;
p2p.presence_resp = wpas_presence_resp;
+ p2p.is_concurrent_session_active = wpas_is_concurrent_session_active;
os_memcpy(wpa_s->global->p2p_dev_addr, wpa_s->own_addr, ETH_ALEN);
os_memcpy(p2p.dev_addr, wpa_s->global->p2p_dev_addr, ETH_ALEN);
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index da827bd..30da097 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -521,6 +521,11 @@
size_t max_ssids;
enum wpa_states prev_state;
+ if (wpa_s->pno || wpa_s->pno_sched_pending) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "Skip scan - PNO is in progress");
+ return;
+ }
+
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
wpa_dbg(wpa_s, MSG_DEBUG, "Skip scan - interface disabled");
return;
@@ -1112,6 +1117,9 @@
params.extra_ies_len = wpabuf_len(extra_ie);
}
+ if (wpa_s->conf->filter_rssi)
+ params.filter_rssi = wpa_s->conf->filter_rssi;
+
scan_params = ¶ms;
scan:
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 3a28534..078856e 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -768,6 +768,7 @@
} hw;
int pno;
+ int pno_sched_pending;
/* WLAN_REASON_* reason codes. Negative if locally generated. */
int disconnect_reason;