summaryrefslogtreecommitdiff
path: root/hostapd
diff options
context:
space:
mode:
authorAndrew Shadura <andrewsh@debian.org>2016-07-21 14:48:54 +0200
committerAndrew Shadura <andrewsh@debian.org>2016-07-21 14:48:54 +0200
commit2b2675a5c8455e6a7224b153a28a6c2b5f1acd70 (patch)
tree3f83c6ef1b28171f58dccff1397bc01be1c01956 /hostapd
parent6e1f9c092d6958a8a1c01629f43941647dc7fc20 (diff)
Imported Upstream version 2.4
Diffstat (limited to 'hostapd')
-rw-r--r--hostapd/Android.mk56
-rw-r--r--hostapd/ChangeLog44
-rw-r--r--hostapd/Makefile82
-rw-r--r--hostapd/README8
-rw-r--r--hostapd/README-WPS9
-rw-r--r--hostapd/android.config6
-rw-r--r--hostapd/config_file.c142
-rw-r--r--hostapd/ctrl_iface.c677
-rw-r--r--hostapd/defconfig9
-rw-r--r--hostapd/hlr_auc_gw.c4
-rw-r--r--hostapd/hostapd.82
-rw-r--r--hostapd/hostapd.conf73
-rw-r--r--hostapd/hostapd_cli.c94
-rw-r--r--hostapd/main.c22
14 files changed, 1060 insertions, 168 deletions
diff --git a/hostapd/Android.mk b/hostapd/Android.mk
index edaf6fc..6fcefdd 100644
--- a/hostapd/Android.mk
+++ b/hostapd/Android.mk
@@ -95,6 +95,7 @@ OBJS += src/ap/preauth_auth.c
OBJS += src/ap/pmksa_cache_auth.c
OBJS += src/ap/ieee802_11_shared.c
OBJS += src/ap/beacon.c
+OBJS += src/ap/bss_load.c
OBJS_d =
OBJS_p =
LIBS =
@@ -133,6 +134,7 @@ OBJS += src/utils/ip_addr.c
OBJS += src/common/ieee802_11_common.c
OBJS += src/common/wpa_common.c
+OBJS += src/common/hw_features_common.c
OBJS += src/eapol_auth/eapol_auth_sm.c
@@ -179,8 +181,6 @@ OBJS += ctrl_iface.c
OBJS += src/ap/ctrl_iface_ap.c
endif
-OBJS += src/crypto/md5.c
-
L_CFLAGS += -DCONFIG_CTRL_IFACE -DCONFIG_CTRL_IFACE_UNIX
ifdef CONFIG_IAPP
@@ -200,6 +200,22 @@ endif
ifdef CONFIG_HS20
NEED_AES_OMAC1=y
+CONFIG_PROXYARP=y
+endif
+
+ifdef CONFIG_PROXYARP
+CONFIG_L2_PACKET=y
+endif
+
+ifdef CONFIG_SUITEB
+L_CFLAGS += -DCONFIG_SUITEB
+NEED_SHA256=y
+NEED_AES_OMAC1=y
+endif
+
+ifdef CONFIG_SUITEB192
+L_CFLAGS += -DCONFIG_SUITEB192
+NEED_SHA384=y
endif
ifdef CONFIG_IEEE80211W
@@ -553,22 +569,6 @@ CONFIG_INTERNAL_RC4=y
CONFIG_INTERNAL_DH_GROUP5=y
endif
-ifeq ($(CONFIG_TLS), nss)
-ifdef TLS_FUNCS
-OBJS += src/crypto/tls_nss.c
-LIBS += -lssl3
-endif
-OBJS += src/crypto/crypto_nss.c
-ifdef NEED_FIPS186_2_PRF
-OBJS += src/crypto/fips_prf_internal.c
-OBJS += src/crypto/sha1-internal.c
-endif
-LIBS += -lnss3
-LIBS_h += -lnss3
-CONFIG_INTERNAL_MD4=y
-CONFIG_INTERNAL_DH_GROUP5=y
-endif
-
ifeq ($(CONFIG_TLS), internal)
ifndef CONFIG_CRYPTO
CONFIG_CRYPTO=internal
@@ -675,7 +675,9 @@ ifdef CONFIG_INTERNAL_AES
AESOBJS += src/crypto/aes-internal.c src/crypto/aes-internal-enc.c
endif
+ifneq ($(CONFIG_TLS), openssl)
AESOBJS += src/crypto/aes-wrap.c
+endif
ifdef NEED_AES_EAX
AESOBJS += src/crypto/aes-eax.c
NEED_AES_CTR=y
@@ -690,9 +692,11 @@ ifdef NEED_AES_OMAC1
AESOBJS += src/crypto/aes-omac1.c
endif
ifdef NEED_AES_UNWRAP
+ifneq ($(CONFIG_TLS), openssl)
NEED_AES_DEC=y
AESOBJS += src/crypto/aes-unwrap.c
endif
+endif
ifdef NEED_AES_CBC
NEED_AES_DEC=y
AESOBJS += src/crypto/aes-cbc.c
@@ -733,6 +737,10 @@ ifdef NEED_SHA1
OBJS += $(SHA1OBJS)
endif
+ifneq ($(CONFIG_TLS), openssl)
+OBJS += src/crypto/md5.c
+endif
+
ifdef NEED_MD5
ifdef CONFIG_INTERNAL_MD5
OBJS += src/crypto/md5-internal.c
@@ -771,6 +779,9 @@ ifdef NEED_TLS_PRF_SHA256
OBJS += src/crypto/sha256-tlsprf.c
endif
endif
+ifdef NEED_SHA384
+L_CFLAGS += -DCONFIG_SHA384
+endif
ifdef NEED_DH_GROUPS
OBJS += src/crypto/dh_groups.c
@@ -854,6 +865,15 @@ OBJS += src/common/gas.c
OBJS += src/ap/gas_serv.c
endif
+ifdef CONFIG_PROXYARP
+L_CFLAGS += -DCONFIG_PROXYARP
+OBJS += src/ap/x_snoop.c
+OBJS += src/ap/dhcp_snoop.c
+ifdef CONFIG_IPV6
+OBJS += src/ap/ndisc_snoop.c
+endif
+endif
+
OBJS += src/drivers/driver_common.c
ifdef CONFIG_ACS
diff --git a/hostapd/ChangeLog b/hostapd/ChangeLog
index f0e4604..e6f8c6a 100644
--- a/hostapd/ChangeLog
+++ b/hostapd/ChangeLog
@@ -1,5 +1,49 @@
ChangeLog for hostapd
+2015-03-15 - v2.4
+ * allow OpenSSL cipher configuration to be set for internal EAP server
+ (openssl_ciphers parameter)
+ * fixed number of small issues based on hwsim test case failures and
+ static analyzer reports
+ * fixed Accounting-Request to not include duplicated Acct-Session-Id
+ * add support for Acct-Multi-Session-Id in RADIUS Accounting messages
+ * add support for PMKSA caching with SAE
+ * add support for generating BSS Load element (bss_load_update_period)
+ * fixed channel switch from VHT to HT
+ * add INTERFACE-ENABLED and INTERFACE-DISABLED ctrl_iface events
+ * add support for learning STA IPv4/IPv6 addresses and configuring
+ ProxyARP support
+ * dropped support for the madwifi driver interface
+ * add support for Suite B (128-bit and 192-bit level) key management and
+ cipher suites
+ * fixed a regression with driver=wired
+ * extend EAPOL-Key msg 1/4 retry workaround for changing SNonce
+ * add BSS_TM_REQ ctrl_iface command to send BSS Transition Management
+ Request frames and BSS-TM-RESP event to indicate response to such
+ frame
+ * add support for EAP Re-Authentication Protocol (ERP)
+ * fixed AP IE in EAPOL-Key 3/4 when both WPA and FT was enabled
+ * fixed a regression in HT 20/40 coex Action frame parsing
+ * set stdout to be line-buffered
+ * add support for vendor specific VHT extension to enable 256 QAM rates
+ (VHT-MCS 8 and 9) on 2.4 GHz band
+ * RADIUS DAS:
+ - extend Disconnect-Request processing to allow matching of multiple
+ sessions
+ - support Acct-Multi-Session-Id as an identifier
+ - allow PMKSA cache entry to be removed without association
+ * expire hostapd STA entry if kernel does not have a matching entry
+ * allow chanlist to be used to specify a subset of channels for ACS
+ * improve ACS behavior on 2.4 GHz band and allow channel bias to be
+ configured with acs_chan_bias parameter
+ * do not reply to a Probe Request frame that includes DSS Parameter Set
+ element in which the channel does not match the current operating
+ channel
+ * add UPDATE_BEACON ctrl_iface command; this can be used to force Beacon
+ frame contents to be updated and to start beaconing on an interface
+ that used start_disabled=1
+ * fixed some RADIUS server failover cases
+
2014-10-09 - v2.3
* fixed number of minor issues identified in static analyzer warnings
* fixed DFS and channel switch operation for multi-BSS cases
diff --git a/hostapd/Makefile b/hostapd/Makefile
index ac6373e..eace68c 100644
--- a/hostapd/Makefile
+++ b/hostapd/Makefile
@@ -6,9 +6,12 @@ ifndef CFLAGS
CFLAGS = -MMD -O2 -Wall -g
endif
+CFLAGS += $(EXTRA_CFLAGS)
CFLAGS += -I$(abspath ../src)
CFLAGS += -I$(abspath ../src/utils)
+export BINDIR ?= /usr/local/bin/
+
# Uncomment following line and set the path to your kernel tree include
# directory if your C library does not include all header files.
# CFLAGS += -DUSE_KERNEL_HEADERS -I/usr/src/linux/include
@@ -59,6 +62,7 @@ OBJS += ../src/ap/preauth_auth.o
OBJS += ../src/ap/pmksa_cache_auth.o
OBJS += ../src/ap/ieee802_11_shared.o
OBJS += ../src/ap/beacon.o
+OBJS += ../src/ap/bss_load.o
OBJS_c = hostapd_cli.o ../src/common/wpa_ctrl.o ../src/utils/os_$(CONFIG_OS).o
@@ -112,6 +116,7 @@ OBJS += ../src/utils/ip_addr.o
OBJS += ../src/common/ieee802_11_common.o
OBJS += ../src/common/wpa_common.o
+OBJS += ../src/common/hw_features_common.o
OBJS += ../src/eapol_auth/eapol_auth_sm.o
@@ -166,8 +171,6 @@ OBJS += ctrl_iface.o
OBJS += ../src/ap/ctrl_iface_ap.o
endif
-OBJS += ../src/crypto/md5.o
-
CFLAGS += -DCONFIG_CTRL_IFACE -DCONFIG_CTRL_IFACE_UNIX
ifdef CONFIG_IAPP
@@ -187,6 +190,22 @@ endif
ifdef CONFIG_HS20
NEED_AES_OMAC1=y
+CONFIG_PROXYARP=y
+endif
+
+ifdef CONFIG_PROXYARP
+CONFIG_L2_PACKET=y
+endif
+
+ifdef CONFIG_SUITEB
+CFLAGS += -DCONFIG_SUITEB
+NEED_SHA256=y
+NEED_AES_OMAC1=y
+endif
+
+ifdef CONFIG_SUITEB192
+CFLAGS += -DCONFIG_SUITEB192
+NEED_SHA384=y
endif
ifdef CONFIG_IEEE80211W
@@ -246,6 +265,12 @@ OBJS += ../src/l2_packet/l2_packet_none.o
endif
+ifdef CONFIG_ERP
+CFLAGS += -DCONFIG_ERP
+NEED_SHA256=y
+NEED_HMAC_SHA256_KDF=y
+endif
+
ifdef CONFIG_EAP_MD5
CFLAGS += -DEAP_SERVER_MD5
OBJS += ../src/eap_server/eap_server_md5.o
@@ -539,22 +564,6 @@ CONFIG_INTERNAL_RC4=y
CONFIG_INTERNAL_DH_GROUP5=y
endif
-ifeq ($(CONFIG_TLS), nss)
-ifdef TLS_FUNCS
-OBJS += ../src/crypto/tls_nss.o
-LIBS += -lssl3
-endif
-OBJS += ../src/crypto/crypto_nss.o
-ifdef NEED_FIPS186_2_PRF
-OBJS += ../src/crypto/fips_prf_internal.o
-SHA1OBJS += ../src/crypto/sha1-internal.o
-endif
-LIBS += -lnss3
-LIBS_h += -lnss3
-CONFIG_INTERNAL_MD4=y
-CONFIG_INTERNAL_DH_GROUP5=y
-endif
-
ifeq ($(CONFIG_TLS), internal)
ifndef CONFIG_CRYPTO
CONFIG_CRYPTO=internal
@@ -661,7 +670,9 @@ ifdef CONFIG_INTERNAL_AES
AESOBJS += ../src/crypto/aes-internal.o ../src/crypto/aes-internal-enc.o
endif
+ifneq ($(CONFIG_TLS), openssl)
AESOBJS += ../src/crypto/aes-wrap.o
+endif
ifdef NEED_AES_EAX
AESOBJS += ../src/crypto/aes-eax.o
NEED_AES_CTR=y
@@ -676,9 +687,11 @@ ifdef NEED_AES_OMAC1
AESOBJS += ../src/crypto/aes-omac1.o
endif
ifdef NEED_AES_UNWRAP
+ifneq ($(CONFIG_TLS), openssl)
NEED_AES_DEC=y
AESOBJS += ../src/crypto/aes-unwrap.o
endif
+endif
ifdef NEED_AES_CBC
NEED_AES_DEC=y
AESOBJS += ../src/crypto/aes-cbc.o
@@ -718,6 +731,10 @@ ifdef NEED_SHA1
OBJS += $(SHA1OBJS)
endif
+ifneq ($(CONFIG_TLS), openssl)
+OBJS += ../src/crypto/md5.o
+endif
+
ifdef NEED_MD5
ifdef CONFIG_INTERNAL_MD5
OBJS += ../src/crypto/md5-internal.o
@@ -755,6 +772,12 @@ endif
ifdef NEED_TLS_PRF_SHA256
OBJS += ../src/crypto/sha256-tlsprf.o
endif
+ifdef NEED_HMAC_SHA256_KDF
+OBJS += ../src/crypto/sha256-kdf.o
+endif
+endif
+ifdef NEED_SHA384
+CFLAGS += -DCONFIG_SHA384
endif
ifdef NEED_DH_GROUPS
@@ -839,6 +862,15 @@ OBJS += ../src/common/gas.o
OBJS += ../src/ap/gas_serv.o
endif
+ifdef CONFIG_PROXYARP
+CFLAGS += -DCONFIG_PROXYARP
+OBJS += ../src/ap/x_snoop.o
+OBJS += ../src/ap/dhcp_snoop.o
+ifdef CONFIG_IPV6
+OBJS += ../src/ap/ndisc_snoop.o
+endif
+endif
+
OBJS += ../src/drivers/driver_common.o
ifdef CONFIG_WPA_CLI_EDIT
@@ -881,6 +913,10 @@ ifeq ($(V), 1)
Q=
E=true
endif
+ifeq ($(QUIET), 1)
+Q=@
+E=true
+endif
ifdef CONFIG_CODE_COVERAGE
%.o: %.c
@@ -901,9 +937,10 @@ verify_config:
exit 1; \
fi
-install: all
- mkdir -p $(DESTDIR)/usr/local/bin
- for i in $(ALL); do cp -f $$i $(DESTDIR)/usr/local/bin/$$i; done
+$(DESTDIR)$(BINDIR)/%: %
+ install -D $(<) $(@)
+
+install: $(addprefix $(DESTDIR)$(BINDIR)/,$(ALL))
../src/drivers/build.hostapd:
@if [ -f ../src/drivers/build.wpa_supplicant ]; then \
@@ -924,7 +961,8 @@ hostapd_cli: $(OBJS_c)
$(Q)$(CC) $(LDFLAGS) -o hostapd_cli $(OBJS_c) $(LIBS_c)
@$(E) " LD " $@
-NOBJS = nt_password_hash.o ../src/crypto/ms_funcs.o $(SHA1OBJS) ../src/crypto/md5.o
+NOBJS = nt_password_hash.o ../src/crypto/ms_funcs.o $(SHA1OBJS)
+NOBJS += ../src/utils/common.o
ifdef NEED_RC4
ifdef CONFIG_INTERNAL_RC4
NOBJS += ../src/crypto/rc4.o
diff --git a/hostapd/README b/hostapd/README
index 50868ee..366b199 100644
--- a/hostapd/README
+++ b/hostapd/README
@@ -2,7 +2,7 @@ hostapd - user space IEEE 802.11 AP and IEEE 802.1X/WPA/WPA2/EAP
Authenticator and RADIUS authentication server
================================================================
-Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi> and contributors
+Copyright (c) 2002-2015, Jouni Malinen <j@w1.fi> and contributors
All Rights Reserved.
This program is licensed under the BSD license (the one with
@@ -74,12 +74,6 @@ Current hardware/software requirements:
Please note that station firmware version needs to be 1.7.0 or newer
to work in WPA mode.
- madwifi driver for cards based on Atheros chip set (ar521x)
- (http://sourceforge.net/projects/madwifi/)
- Please note that you will need to add the correct path for
- madwifi driver root directory in .config (see defconfig file for
- an example: CFLAGS += -I<path>)
-
mac80211-based drivers that support AP mode (with driver=nl80211).
This includes drivers for Atheros (ath9k) and Broadcom (b43)
chipsets.
diff --git a/hostapd/README-WPS b/hostapd/README-WPS
index bb7d35f..d5f713a 100644
--- a/hostapd/README-WPS
+++ b/hostapd/README-WPS
@@ -58,10 +58,9 @@ hostapd configuration
WPS is an optional component that needs to be enabled in hostapd build
configuration (.config). Here is an example configuration that
-includes WPS support and uses madwifi driver interface:
+includes WPS support and uses nl80211 driver interface:
-CONFIG_DRIVER_MADWIFI=y
-CFLAGS += -I/usr/src/madwifi-0.9.3
+CONFIG_DRIVER_NL80211=y
CONFIG_WPS=y
CONFIG_WPS_UPNP=y
@@ -74,8 +73,8 @@ Following section shows an example runtime configuration
(hostapd.conf) that enables WPS:
# Configure the driver and network interface
-driver=madwifi
-interface=ath0
+driver=nl80211
+interface=wlan0
# WPA2-Personal configuration for the AP
ssid=wps-test
diff --git a/hostapd/android.config b/hostapd/android.config
index ad83308..938aa54 100644
--- a/hostapd/android.config
+++ b/hostapd/android.config
@@ -15,10 +15,6 @@
# Driver interface for wired authenticator
#CONFIG_DRIVER_WIRED=y
-# Driver interface for madwifi driver
-#CONFIG_DRIVER_MADWIFI=y
-#CFLAGS += -I../../madwifi # change to the madwifi source directory
-
# Driver interface for drivers using the nl80211 kernel interface
#CONFIG_DRIVER_NL80211=y
# driver_nl80211.c requires a rather new libnl (version 1.1) which may not be
@@ -132,7 +128,7 @@ CONFIG_IPV6=y
#CONFIG_IEEE80211R=y
# Use the hostapd's IEEE 802.11 authentication (ACL), but without
-# the IEEE 802.11 Management capability (e.g., madwifi or FreeBSD/net80211)
+# the IEEE 802.11 Management capability (e.g., FreeBSD/net80211)
#CONFIG_DRIVER_RADIUS_ACL=y
# IEEE 802.11n (High Throughput) support
diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index 32e3c49..53143f7 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -1,6 +1,6 @@
/*
* hostapd / Configuration file parser
- * Copyright (c) 2003-2014, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -216,7 +216,7 @@ static int hostapd_config_read_eap_user(const char *fname,
FILE *f;
char buf[512], *pos, *start, *pos2;
int line = 0, ret = 0, num_methods;
- struct hostapd_eap_user *user = NULL, *tail = NULL;
+ struct hostapd_eap_user *user = NULL, *tail = NULL, *new_user = NULL;
if (!fname)
return 0;
@@ -494,7 +494,7 @@ static int hostapd_config_read_eap_user(const char *fname,
done:
if (tail == NULL) {
- tail = conf->eap_user = user;
+ tail = new_user = user;
} else {
tail->next = user;
tail = user;
@@ -510,6 +510,18 @@ static int hostapd_config_read_eap_user(const char *fname,
fclose(f);
+ if (ret == 0) {
+ user = conf->eap_user;
+ while (user) {
+ struct hostapd_eap_user *prev;
+
+ prev = user;
+ user = user->next;
+ hostapd_config_free_eap_user(prev);
+ }
+ conf->eap_user = new_user;
+ }
+
return ret;
}
#endif /* EAP_SERVER */
@@ -680,6 +692,14 @@ static int hostapd_config_parse_key_mgmt(int line, const char *value)
else if (os_strcmp(start, "FT-SAE") == 0)
val |= WPA_KEY_MGMT_FT_SAE;
#endif /* CONFIG_SAE */
+#ifdef CONFIG_SUITEB
+ else if (os_strcmp(start, "WPA-EAP-SUITE-B") == 0)
+ val |= WPA_KEY_MGMT_IEEE8021X_SUITE_B;
+#endif /* CONFIG_SUITEB */
+#ifdef CONFIG_SUITEB192
+ else if (os_strcmp(start, "WPA-EAP-SUITE-B-192") == 0)
+ val |= WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
+#endif /* CONFIG_SUITEB192 */
else {
wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'",
line, start);
@@ -1836,6 +1856,48 @@ static struct wpabuf * hostapd_parse_bin(const char *buf)
#endif /* CONFIG_WPS_NFC */
+#ifdef CONFIG_ACS
+static int hostapd_config_parse_acs_chan_bias(struct hostapd_config *conf,
+ char *pos)
+{
+ struct acs_bias *bias = NULL, *tmp;
+ unsigned int num = 0;
+ char *end;
+
+ while (*pos) {
+ tmp = os_realloc_array(bias, num + 1, sizeof(*bias));
+ if (!tmp)
+ goto fail;
+ bias = tmp;
+
+ bias[num].channel = atoi(pos);
+ if (bias[num].channel <= 0)
+ goto fail;
+ pos = os_strchr(pos, ':');
+ if (!pos)
+ goto fail;
+ pos++;
+ bias[num].bias = strtod(pos, &end);
+ if (end == pos || bias[num].bias < 0.0)
+ goto fail;
+ pos = end;
+ if (*pos != ' ' && *pos != '\0')
+ goto fail;
+ num++;
+ }
+
+ os_free(conf->acs_chan_bias);
+ conf->acs_chan_bias = bias;
+ conf->num_acs_chan_bias = num;
+
+ return 0;
+fail:
+ os_free(bias);
+ return -1;
+}
+#endif /* CONFIG_ACS */
+
+
static int hostapd_config_fill(struct hostapd_config *conf,
struct hostapd_bss_config *bss,
char *buf, char *pos, int line)
@@ -1865,6 +1927,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
line, pos);
return 1;
}
+ } else if (os_strcmp(buf, "driver_params") == 0) {
+ os_free(conf->driver_params);
+ conf->driver_params = os_strdup(pos);
} else if (os_strcmp(buf, "debug") == 0) {
wpa_printf(MSG_DEBUG, "Line %d: DEPRECATED: 'debug' configuration variable is not used anymore",
line);
@@ -1984,6 +2049,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
} else if (os_strcmp(buf, "dh_file") == 0) {
os_free(bss->dh_file);
bss->dh_file = os_strdup(pos);
+ } else if (os_strcmp(buf, "openssl_ciphers") == 0) {
+ os_free(bss->openssl_ciphers);
+ bss->openssl_ciphers = os_strdup(pos);
} else if (os_strcmp(buf, "fragment_size") == 0) {
bss->fragment_size = atoi(pos);
#ifdef EAP_SERVER_FAST
@@ -2044,6 +2112,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
} else if (os_strcmp(buf, "pwd_group") == 0) {
bss->pwd_group = atoi(pos);
#endif /* EAP_SERVER_PWD */
+ } else if (os_strcmp(buf, "eap_server_erp") == 0) {
+ bss->eap_server_erp = atoi(pos);
#endif /* EAP_SERVER */
} else if (os_strcmp(buf, "eap_message") == 0) {
char *term;
@@ -2063,6 +2133,11 @@ static int hostapd_config_fill(struct hostapd_config *conf,
(term - bss->eap_req_id_text) - 1);
bss->eap_req_id_text_len--;
}
+ } else if (os_strcmp(buf, "erp_send_reauth_start") == 0) {
+ bss->erp_send_reauth_start = atoi(pos);
+ } else if (os_strcmp(buf, "erp_domain") == 0) {
+ os_free(bss->erp_domain);
+ bss->erp_domain = os_strdup(pos);
} else if (os_strcmp(buf, "wep_key_len_broadcast") == 0) {
bss->default_wep_key_len = atoi(pos);
if (bss->default_wep_key_len > 13) {
@@ -2114,6 +2189,14 @@ static int hostapd_config_fill(struct hostapd_config *conf,
os_free(bss->nas_identifier);
bss->nas_identifier = os_strdup(pos);
#ifndef CONFIG_NO_RADIUS
+ } else if (os_strcmp(buf, "radius_client_addr") == 0) {
+ if (hostapd_parse_ip_addr(pos, &bss->radius->client_addr)) {
+ wpa_printf(MSG_ERROR,
+ "Line %d: invalid IP address '%s'",
+ line, pos);
+ return 1;
+ }
+ bss->radius->force_client_addr = 1;
} else if (os_strcmp(buf, "auth_server_addr") == 0) {
if (hostapd_config_read_radius_addr(
&bss->radius->auth_servers,
@@ -2125,6 +2208,15 @@ static int hostapd_config_fill(struct hostapd_config *conf,
return 1;
}
} else if (bss->radius->auth_server &&
+ os_strcmp(buf, "auth_server_addr_replace") == 0) {
+ if (hostapd_parse_ip_addr(pos,
+ &bss->radius->auth_server->addr)) {
+ wpa_printf(MSG_ERROR,
+ "Line %d: invalid IP address '%s'",
+ line, pos);
+ return 1;
+ }
+ } else if (bss->radius->auth_server &&
os_strcmp(buf, "auth_server_port") == 0) {
bss->radius->auth_server->port = atoi(pos);
} else if (bss->radius->auth_server &&
@@ -2150,6 +2242,15 @@ static int hostapd_config_fill(struct hostapd_config *conf,
return 1;
}
} else if (bss->radius->acct_server &&
+ os_strcmp(buf, "acct_server_addr_replace") == 0) {
+ if (hostapd_parse_ip_addr(pos,
+ &bss->radius->acct_server->addr)) {
+ wpa_printf(MSG_ERROR,
+ "Line %d: invalid IP address '%s'",
+ line, pos);
+ return 1;
+ }
+ } else if (bss->radius->acct_server &&
os_strcmp(buf, "acct_server_port") == 0) {
bss->radius->acct_server->port = atoi(pos);
} else if (bss->radius->acct_server &&
@@ -2250,12 +2351,11 @@ static int hostapd_config_fill(struct hostapd_config *conf,
os_free(bss->ssid.wpa_passphrase);
bss->ssid.wpa_passphrase = os_strdup(pos);
if (bss->ssid.wpa_passphrase) {
- os_free(bss->ssid.wpa_psk);
- bss->ssid.wpa_psk = NULL;
+ hostapd_config_clear_wpa_psk(&bss->ssid.wpa_psk);
bss->ssid.wpa_passphrase_set = 1;
}
} else if (os_strcmp(buf, "wpa_psk") == 0) {
- os_free(bss->ssid.wpa_psk);
+ hostapd_config_clear_wpa_psk(&bss->ssid.wpa_psk);
bss->ssid.wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk));
if (bss->ssid.wpa_psk == NULL)
return 1;
@@ -2263,8 +2363,7 @@ static int hostapd_config_fill(struct hostapd_config *conf,
pos[PMK_LEN * 2] != '\0') {
wpa_printf(MSG_ERROR, "Line %d: Invalid PSK '%s'.",
line, pos);
- os_free(bss->ssid.wpa_psk);
- bss->ssid.wpa_psk = NULL;
+ hostapd_config_clear_wpa_psk(&bss->ssid.wpa_psk);
return 1;
}
bss->ssid.wpa_psk->group = 1;
@@ -2405,9 +2504,6 @@ static int hostapd_config_fill(struct hostapd_config *conf,
} else if (os_strcmp(buf, "radius_server_ipv6") == 0) {
bss->radius_server_ipv6 = atoi(pos);
#endif /* RADIUS_SERVER */
- } else if (os_strcmp(buf, "test_socket") == 0) {
- os_free(bss->test_socket);
- bss->test_socket = os_strdup(pos);
} else if (os_strcmp(buf, "use_pae_group_addr") == 0) {
bss->use_pae_group_addr = atoi(pos);
} else if (os_strcmp(buf, "hw_mode") == 0) {
@@ -2478,6 +2574,12 @@ static int hostapd_config_fill(struct hostapd_config *conf,
return 1;
}
conf->acs_num_scans = val;
+ } else if (os_strcmp(buf, "acs_chan_bias") == 0) {
+ if (hostapd_config_parse_acs_chan_bias(conf, pos)) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid acs_chan_bias",
+ line);
+ return -1;
+ }
#endif /* CONFIG_ACS */
} else if (os_strcmp(buf, "dtim_period") == 0) {
bss->dtim_period = atoi(pos);
@@ -2486,6 +2588,15 @@ static int hostapd_config_fill(struct hostapd_config *conf,
line, bss->dtim_period);
return 1;
}
+ } else if (os_strcmp(buf, "bss_load_update_period") == 0) {
+ bss->bss_load_update_period = atoi(pos);
+ if (bss->bss_load_update_period < 0 ||
+ bss->bss_load_update_period > 100) {
+ wpa_printf(MSG_ERROR,
+ "Line %d: invalid bss_load_update_period %d",
+ line, bss->bss_load_update_period);
+ return 1;
+ }
} else if (os_strcmp(buf, "rts_threshold") == 0) {
conf->rts_threshold = atoi(pos);
if (conf->rts_threshold < 0 || conf->rts_threshold > 2347) {
@@ -2669,6 +2780,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
conf->vht_oper_centr_freq_seg0_idx = atoi(pos);
} else if (os_strcmp(buf, "vht_oper_centr_freq_seg1_idx") == 0) {
conf->vht_oper_centr_freq_seg1_idx = atoi(pos);
+ } else if (os_strcmp(buf, "vendor_vht") == 0) {
+ bss->vendor_vht = atoi(pos);
#endif /* CONFIG_IEEE80211AC */
} else if (os_strcmp(buf, "max_listen_interval") == 0) {
bss->max_listen_interval = atoi(pos);
@@ -2996,6 +3109,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
bss->hs20 = atoi(pos);
} else if (os_strcmp(buf, "disable_dgaf") == 0) {
bss->disable_dgaf = atoi(pos);
+ } else if (os_strcmp(buf, "proxy_arp") == 0) {
+ bss->proxy_arp = atoi(pos);
} else if (os_strcmp(buf, "osen") == 0) {
bss->osen = atoi(pos);
} else if (os_strcmp(buf, "anqp_domain_id") == 0) {
@@ -3106,6 +3221,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
pos++;
WPA_PUT_LE16(&bss->bss_load_test[3], atoi(pos));
bss->bss_load_test_set = 1;
+ } else if (os_strcmp(buf, "radio_measurements") == 0) {
+ bss->radio_measurements = atoi(pos);
#endif /* CONFIG_TESTING_OPTIONS */
} else if (os_strcmp(buf, "vendor_elements") == 0) {
struct wpabuf *elems;
@@ -3156,6 +3273,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
conf->local_pwr_constraint = val;
} else if (os_strcmp(buf, "spectrum_mgmt_required") == 0) {
conf->spectrum_mgmt_required = atoi(pos);
+ } else if (os_strcmp(buf, "wowlan_triggers") == 0) {
+ os_free(bss->wowlan_triggers);
+ bss->wowlan_triggers = os_strdup(pos);
} else {
wpa_printf(MSG_ERROR,
"Line %d: unknown configuration item '%s'",
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index 591c395..86f1aa6 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -1,6 +1,6 @@
/*
* hostapd / UNIX domain socket -based control interface
- * Copyright (c) 2004-2014, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -10,6 +10,11 @@
#ifndef CONFIG_NATIVE_WINDOWS
+#ifdef CONFIG_TESTING_OPTIONS
+#include <net/ethernet.h>
+#include <netinet/ip.h>
+#endif /* CONFIG_TESTING_OPTIONS */
+
#include <sys/un.h>
#include <sys/stat.h>
#include <stddef.h>
@@ -18,9 +23,11 @@
#include "utils/eloop.h"
#include "common/version.h"
#include "common/ieee802_11_defs.h"
+#include "crypto/tls.h"
#include "drivers/driver.h"
#include "radius/radius_client.h"
#include "radius/radius_server.h"
+#include "l2_packet/l2_packet.h"
#include "ap/hostapd.h"
#include "ap/ap_config.h"
#include "ap/ieee802_1x.h"
@@ -33,6 +40,7 @@
#include "ap/hs20.h"
#include "ap/wnm_ap.h"
#include "ap/wpa_auth.h"
+#include "ap/beacon.h"
#include "wps/wps_defs.h"
#include "wps/wps.h"
#include "config_file.h"
@@ -240,14 +248,14 @@ static int hostapd_ctrl_iface_wps_check_pin(
if (!wps_pin_valid(pin_val)) {
wpa_printf(MSG_DEBUG, "WPS: Invalid checksum digit");
ret = os_snprintf(buf, buflen, "FAIL-CHECKSUM\n");
- if (ret < 0 || (size_t) ret >= buflen)
+ if (os_snprintf_error(buflen, ret))
return -1;
return ret;
}
}
ret = os_snprintf(buf, buflen, "%s", pin);
- if (ret < 0 || (size_t) ret >= buflen)
+ if (os_snprintf_error(buflen, ret))
return -1;
return ret;
@@ -578,7 +586,7 @@ static int hostapd_ctrl_iface_wps_get_status(struct hostapd_data *hapd,
ret = os_snprintf(pos, end - pos, "PBC Status: %s\n",
pbc_status_str(hapd->wps_stats.pbc_status));
- if (ret < 0 || ret >= end - pos)
+ if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
@@ -588,7 +596,7 @@ static int hostapd_ctrl_iface_wps_get_status(struct hostapd_data *hapd,
(hapd->wps_stats.status == WPS_STATUS_FAILURE ?
"Failed" : "None")));
- if (ret < 0 || ret >= end - pos)
+ if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
@@ -599,7 +607,7 @@ static int hostapd_ctrl_iface_wps_get_status(struct hostapd_data *hapd,
"Failure Reason: %s\n",
wps_ei_str(hapd->wps_stats.failure_reason));
- if (ret < 0 || ret >= end - pos)
+ if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
}
@@ -608,7 +616,7 @@ static int hostapd_ctrl_iface_wps_get_status(struct hostapd_data *hapd,
ret = os_snprintf(pos, end - pos, "Peer Address: " MACSTR "\n",
MAC2STR(hapd->wps_stats.peer_addr));
- if (ret < 0 || ret >= end - pos)
+ if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
}
@@ -857,6 +865,193 @@ static int hostapd_ctrl_iface_ess_disassoc(struct hostapd_data *hapd,
return wnm_send_ess_disassoc_imminent(hapd, sta, url, disassoc_timer);
}
+
+static int hostapd_ctrl_iface_bss_tm_req(struct hostapd_data *hapd,
+ const char *cmd)
+{
+ u8 addr[ETH_ALEN];
+ const char *pos, *end;
+ int disassoc_timer = 0;
+ struct sta_info *sta;
+ u8 req_mode = 0, valid_int = 0x01;
+ u8 bss_term_dur[12];
+ char *url = NULL;
+ int ret;
+ u8 nei_rep[1000];
+ u8 *nei_pos = nei_rep;
+
+ if (hwaddr_aton(cmd, addr)) {
+ wpa_printf(MSG_DEBUG, "Invalid STA MAC address");
+ return -1;
+ }
+
+ sta = ap_get_sta(hapd, addr);
+ if (sta == NULL) {
+ wpa_printf(MSG_DEBUG, "Station " MACSTR
+ " not found for BSS TM Request message",
+ MAC2STR(addr));
+ return -1;
+ }
+
+ pos = os_strstr(cmd, " disassoc_timer=");
+ if (pos) {
+ pos += 16;
+ disassoc_timer = atoi(pos);
+ if (disassoc_timer < 0 || disassoc_timer > 65535) {
+ wpa_printf(MSG_DEBUG, "Invalid disassoc_timer");
+ return -1;
+ }
+ }
+
+ pos = os_strstr(cmd, " valid_int=");
+ if (pos) {
+ pos += 11;
+ valid_int = atoi(pos);
+ }
+
+ pos = os_strstr(cmd, " bss_term=");
+ if (pos) {
+ pos += 10;
+ req_mode |= WNM_BSS_TM_REQ_BSS_TERMINATION_INCLUDED;
+ /* TODO: TSF configurable/learnable */
+ bss_term_dur[0] = 4; /* Subelement ID */
+ bss_term_dur[1] = 10; /* Length */
+ os_memset(bss_term_dur, 2, 8);
+ end = os_strchr(pos, ',');
+ if (end == NULL) {
+ wpa_printf(MSG_DEBUG, "Invalid bss_term data");
+ return -1;
+ }
+ end++;
+ WPA_PUT_LE16(&bss_term_dur[10], atoi(end));
+ }
+
+
+ /*
+ * BSS Transition Candidate List Entries - Neighbor Report elements
+ * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
+ * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
+ */
+ pos = cmd;
+ while (pos) {
+ u8 *nei_start;
+ long int val;
+ char *endptr, *tmp;
+
+ pos = os_strstr(pos, " neighbor=");
+ if (!pos)
+ break;
+ if (nei_pos + 15 > nei_rep + sizeof(nei_rep)) {
+ wpa_printf(MSG_DEBUG,
+ "Not enough room for additional neighbor");
+ return -1;
+ }
+ pos += 10;
+
+ nei_start = nei_pos;
+ *nei_pos++ = WLAN_EID_NEIGHBOR_REPORT;
+ nei_pos++; /* length to be filled in */
+
+ if (hwaddr_aton(pos, nei_pos)) {
+ wpa_printf(MSG_DEBUG, "Invalid BSSID");
+ return -1;
+ }
+ nei_pos += ETH_ALEN;
+ pos += 17;
+ if (*pos != ',') {
+ wpa_printf(MSG_DEBUG, "Missing BSSID Information");
+ return -1;
+ }
+ pos++;
+
+ val = strtol(pos, &endptr, 0);
+ WPA_PUT_LE32(nei_pos, val);
+ nei_pos += 4;
+ if (*endptr != ',') {
+ wpa_printf(MSG_DEBUG, "Missing Operating Class");
+ return -1;
+ }
+ pos = endptr + 1;
+
+ *nei_pos++ = atoi(pos); /* Operating Class */
+ pos = os_strchr(pos, ',');
+ if (pos == NULL) {
+ wpa_printf(MSG_DEBUG, "Missing Channel Number");
+ return -1;
+ }
+ pos++;
+
+ *nei_pos++ = atoi(pos); /* Channel Number */
+ pos = os_strchr(pos, ',');
+ if (pos == NULL) {
+ wpa_printf(MSG_DEBUG, "Missing PHY Type");
+ return -1;
+ }
+ pos++;
+
+ *nei_pos++ = atoi(pos); /* PHY Type */
+ end = os_strchr(pos, ' ');
+ tmp = os_strchr(pos, ',');
+ if (tmp && (!end || tmp < end)) {
+ /* Optional Subelements (hexdump) */
+ size_t len;
+
+ pos = tmp + 1;
+ end = os_strchr(pos, ' ');
+ if (end)
+ len = end - pos;
+ else
+ len = os_strlen(pos);
+ if (nei_pos + len / 2 > nei_rep + sizeof(nei_rep)) {
+ wpa_printf(MSG_DEBUG,
+ "Not enough room for neighbor subelements");
+ return -1;
+ }
+ if (len & 0x01 ||
+ hexstr2bin(pos, nei_pos, len / 2) < 0) {
+ wpa_printf(MSG_DEBUG,
+ "Invalid neighbor subelement info");
+ return -1;
+ }
+ nei_pos += len / 2;
+ pos = end;
+ }
+
+ nei_start[1] = nei_pos - nei_start - 2;
+ }
+
+ pos = os_strstr(cmd, " url=");
+ if (pos) {
+ size_t len;
+ pos += 5;
+ end = os_strchr(pos, ' ');
+ if (end)
+ len = end - pos;
+ else
+ len = os_strlen(pos);
+ url = os_malloc(len + 1);
+ if (url == NULL)
+ return -1;
+ os_memcpy(url, pos, len);
+ url[len] = '\0';
+ req_mode |= WNM_BSS_TM_REQ_ESS_DISASSOC_IMMINENT;
+ }
+
+ if (os_strstr(cmd, " pref=1"))
+ req_mode |= WNM_BSS_TM_REQ_PREF_CAND_LIST_INCLUDED;
+ if (os_strstr(cmd, " abridged=1"))
+ req_mode |= WNM_BSS_TM_REQ_ABRIDGED;
+ if (os_strstr(cmd, " disassoc_imminent=1"))
+ req_mode |= WNM_BSS_TM_REQ_DISASSOC_IMMINENT;
+
+ ret = wnm_send_bss_tm_req(hapd, sta, req_mode, disassoc_timer,
+ valid_int, bss_term_dur, url,
+ nei_pos > nei_rep ? nei_rep : NULL,
+ nei_pos - nei_rep);
+ os_free(url);
+ return ret;
+}
+
#endif /* CONFIG_WNM */
@@ -874,7 +1069,7 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
MAC2STR(hapd->own_addr),
wpa_ssid_txt(hapd->conf->ssid.ssid,
hapd->conf->ssid.ssid_len));
- if (ret < 0 || ret >= end - pos)
+ if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
@@ -883,7 +1078,7 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
hapd->conf->wps_state == 0 ? "disabled" :
(hapd->conf->wps_state == 1 ? "not configured" :
"configured"));
- if (ret < 0 || ret >= end - pos)
+ if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
@@ -891,7 +1086,7 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
hapd->conf->ssid.wpa_passphrase) {
ret = os_snprintf(pos, end - pos, "passphrase=%s\n",
hapd->conf->ssid.wpa_passphrase);
- if (ret < 0 || ret >= end - pos)
+ if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
}
@@ -903,7 +1098,7 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
wpa_snprintf_hex(hex, sizeof(hex),
hapd->conf->ssid.wpa_psk->psk, PMK_LEN);
ret = os_snprintf(pos, end - pos, "psk=%s\n", hex);
- if (ret < 0 || ret >= end - pos)
+ if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
}
@@ -911,39 +1106,39 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
if (hapd->conf->wpa && hapd->conf->wpa_key_mgmt) {
ret = os_snprintf(pos, end - pos, "key_mgmt=");
- if (ret < 0 || ret >= end - pos)
+ if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) {
ret = os_snprintf(pos, end - pos, "WPA-PSK ");
- if (ret < 0 || ret >= end - pos)
+ if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
}
if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
ret = os_snprintf(pos, end - pos, "WPA-EAP ");
- if (ret < 0 || ret >= end - pos)
+ if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
}
#ifdef CONFIG_IEEE80211R
if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_PSK) {
ret = os_snprintf(pos, end - pos, "FT-PSK ");
- if (ret < 0 || ret >= end - pos)
+ if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
}
if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) {
ret = os_snprintf(pos, end - pos, "FT-EAP ");
- if (ret < 0 || ret >= end - pos)
+ if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
}
#ifdef CONFIG_SAE
if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_SAE) {
ret = os_snprintf(pos, end - pos, "FT-SAE ");
- if (ret < 0 || ret >= end - pos)
+ if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
}
@@ -952,13 +1147,13 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
#ifdef CONFIG_IEEE80211W
if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK_SHA256) {
ret = os_snprintf(pos, end - pos, "WPA-PSK-SHA256 ");
- if (ret < 0 || ret >= end - pos)
+ if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
}
if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) {
ret = os_snprintf(pos, end - pos, "WPA-EAP-SHA256 ");
- if (ret < 0 || ret >= end - pos)
+ if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
}
@@ -966,14 +1161,28 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
#ifdef CONFIG_SAE
if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_SAE) {
ret = os_snprintf(pos, end - pos, "SAE ");
- if (ret < 0 || ret >= end - pos)
+ if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
}
#endif /* CONFIG_SAE */
+ if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
+ ret = os_snprintf(pos, end - pos, "WPA-EAP-SUITE-B ");
+ if (os_snprintf_error(end - pos, ret))
+ return pos - buf;
+ pos += ret;
+ }
+ if (hapd->conf->wpa_key_mgmt &
+ WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
+ ret = os_snprintf(pos, end - pos,
+ "WPA-EAP-SUITE-B-192 ");
+ if (os_snprintf_error(end - pos, ret))
+ return pos - buf;
+ pos += ret;
+ }
ret = os_snprintf(pos, end - pos, "\n");
- if (ret < 0 || ret >= end - pos)
+ if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
}
@@ -981,14 +1190,14 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
if (hapd->conf->wpa) {
ret = os_snprintf(pos, end - pos, "group_cipher=%s\n",
wpa_cipher_txt(hapd->conf->wpa_group));
- if (ret < 0 || ret >= end - pos)
+ if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
}
if ((hapd->conf->wpa & WPA_PROTO_RSN) && hapd->conf->rsn_pairwise) {
ret = os_snprintf(pos, end - pos, "rsn_pairwise_cipher=");
- if (ret < 0 || ret >= end - pos)
+ if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
@@ -999,14 +1208,14 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
pos += ret;
ret = os_snprintf(pos, end - pos, "\n");
- if (ret < 0 || ret >= end - pos)
+ if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
}
if ((hapd->conf->wpa & WPA_PROTO_WPA) && hapd->conf->wpa_pairwise) {
ret = os_snprintf(pos, end - pos, "wpa_pairwise_cipher=");
- if (ret < 0 || ret >= end - pos)
+ if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
@@ -1017,7 +1226,7 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
pos += ret;
ret = os_snprintf(pos, end - pos, "\n");
- if (ret < 0 || ret >= end - pos)
+ if (os_snprintf_error(end - pos, ret))
return pos - buf;
pos += ret;
}
@@ -1074,6 +1283,8 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd)
#ifdef CONFIG_TESTING_OPTIONS
} else if (os_strcasecmp(cmd, "ext_mgmt_frame_handling") == 0) {
hapd->ext_mgmt_frame_handling = atoi(value);
+ } else if (os_strcasecmp(cmd, "ext_eapol_frame_io") == 0) {
+ hapd->ext_eapol_frame_io = atoi(value);
#endif /* CONFIG_TESTING_OPTIONS */
} else {
struct sta_info *sta;
@@ -1122,7 +1333,12 @@ static int hostapd_ctrl_iface_get(struct hostapd_data *hapd, char *cmd,
if (os_strcmp(cmd, "version") == 0) {
res = os_snprintf(buf, buflen, "%s", VERSION_STR);
- if (res < 0 || (unsigned int) res >= buflen)
+ if (os_snprintf_error(buflen, res))
+ return -1;
+ return res;
+ } else if (os_strcmp(cmd, "tls_library") == 0) {
+ res = tls_get_library_version(buf, buflen);
+ if (os_snprintf_error(buflen, res))
return -1;
return res;
}
@@ -1249,6 +1465,287 @@ static int hostapd_ctrl_iface_mgmt_tx(struct hostapd_data *hapd, char *cmd)
return res;
}
+
+static int hostapd_ctrl_iface_eapol_rx(struct hostapd_data *hapd, char *cmd)
+{
+ char *pos;
+ u8 src[ETH_ALEN], *buf;
+ int used;
+ size_t len;
+
+ wpa_printf(MSG_DEBUG, "External EAPOL RX: %s", cmd);
+
+ pos = cmd;
+ used = hwaddr_aton2(pos, src);
+ if (used < 0)
+ return -1;
+ pos += used;
+ while (*pos == ' ')
+ pos++;
+
+ len = os_strlen(pos);
+ if (len & 1)
+ return -1;
+ len /= 2;
+
+ buf = os_malloc(len);
+ if (buf == NULL)
+ return -1;
+
+ if (hexstr2bin(pos, buf, len) < 0) {
+ os_free(buf);
+ return -1;
+ }
+
+ ieee802_1x_receive(hapd, src, buf, len);
+ os_free(buf);
+
+ return 0;
+}
+
+
+static u16 ipv4_hdr_checksum(const void *buf, size_t len)
+{
+ size_t i;
+ u32 sum = 0;
+ const u16 *pos = buf;
+
+ for (i = 0; i < len / 2; i++)
+ sum += *pos++;
+
+ while (sum >> 16)
+ sum = (sum & 0xffff) + (sum >> 16);
+
+ return sum ^ 0xffff;
+}
+
+
+#define HWSIM_PACKETLEN 1500
+#define HWSIM_IP_LEN (HWSIM_PACKETLEN - sizeof(struct ether_header))
+
+void hostapd_data_test_rx(void *ctx, const u8 *src_addr, const u8 *buf,
+ size_t len)
+{
+ struct hostapd_data *hapd = ctx;
+ const struct ether_header *eth;
+ const struct iphdr *ip;
+ const u8 *pos;
+ unsigned int i;
+
+ if (len != HWSIM_PACKETLEN)
+ return;
+
+ eth = (const struct ether_header *) buf;
+ ip = (const struct iphdr *) (eth + 1);
+ pos = (const u8 *) (ip + 1);
+
+ if (ip->ihl != 5 || ip->version != 4 ||
+ ntohs(ip->tot_len) != HWSIM_IP_LEN)
+ return;
+
+ for (i = 0; i < HWSIM_IP_LEN - sizeof(*ip); i++) {
+ if (*pos != (u8) i)
+ return;
+ pos++;
+ }
+
+ wpa_msg(hapd->msg_ctx, MSG_INFO, "DATA-TEST-RX " MACSTR " " MACSTR,
+ MAC2STR(eth->ether_dhost), MAC2STR(eth->ether_shost));
+}
+
+
+static int hostapd_ctrl_iface_data_test_config(struct hostapd_data *hapd,
+ char *cmd)
+{
+ int enabled = atoi(cmd);
+ char *pos;
+ const char *ifname;
+
+ if (!enabled) {
+ if (hapd->l2_test) {
+ l2_packet_deinit(hapd->l2_test);
+ hapd->l2_test = NULL;
+ wpa_dbg(hapd->msg_ctx, MSG_DEBUG,
+ "test data: Disabled");
+ }
+ return 0;
+ }
+
+ if (hapd->l2_test)
+ return 0;
+
+ pos = os_strstr(cmd, " ifname=");
+ if (pos)
+ ifname = pos + 8;
+ else
+ ifname = hapd->conf->iface;
+
+ hapd->l2_test = l2_packet_init(ifname, hapd->own_addr,
+ ETHERTYPE_IP, hostapd_data_test_rx,
+ hapd, 1);
+ if (hapd->l2_test == NULL)
+ return -1;
+
+ wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "test data: Enabled");
+
+ return 0;
+}
+
+
+static int hostapd_ctrl_iface_data_test_tx(struct hostapd_data *hapd, char *cmd)
+{
+ u8 dst[ETH_ALEN], src[ETH_ALEN];
+ char *pos;
+ int used;
+ long int val;
+ u8 tos;
+ u8 buf[HWSIM_PACKETLEN];
+ struct ether_header *eth;
+ struct iphdr *ip;
+ u8 *dpos;
+ unsigned int i;
+
+ if (hapd->l2_test == NULL)
+ return -1;
+
+ /* format: <dst> <src> <tos> */
+
+ pos = cmd;
+ used = hwaddr_aton2(pos, dst);
+ if (used < 0)
+ return -1;
+ pos += used;
+ while (*pos == ' ')
+ pos++;
+ used = hwaddr_aton2(pos, src);
+ if (used < 0)
+ return -1;
+ pos += used;
+
+ val = strtol(pos, NULL, 0);
+ if (val < 0 || val > 0xff)
+ return -1;
+ tos = val;
+
+ eth = (struct ether_header *) buf;
+ os_memcpy(eth->ether_dhost, dst, ETH_ALEN);
+ os_memcpy(eth->ether_shost, src, ETH_ALEN);
+ eth->ether_type = htons(ETHERTYPE_IP);
+ ip = (struct iphdr *) (eth + 1);
+ os_memset(ip, 0, sizeof(*ip));
+ ip->ihl = 5;
+ ip->version = 4;
+ ip->ttl = 64;
+ ip->tos = tos;
+ ip->tot_len = htons(HWSIM_IP_LEN);
+ ip->protocol = 1;
+ ip->saddr = htonl(192 << 24 | 168 << 16 | 1 << 8 | 1);
+ ip->daddr = htonl(192 << 24 | 168 << 16 | 1 << 8 | 2);
+ ip->check = ipv4_hdr_checksum(ip, sizeof(*ip));
+ dpos = (u8 *) (ip + 1);
+ for (i = 0; i < HWSIM_IP_LEN - sizeof(*ip); i++)
+ *dpos++ = i;
+
+ if (l2_packet_send(hapd->l2_test, dst, ETHERTYPE_IP, buf,
+ HWSIM_PACKETLEN) < 0)
+ return -1;
+
+ wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "test data: TX dst=" MACSTR
+ " src=" MACSTR " tos=0x%x", MAC2STR(dst), MAC2STR(src), tos);
+
+ return 0;
+}
+
+
+static int hostapd_ctrl_iface_data_test_frame(struct hostapd_data *hapd,
+ char *cmd)
+{
+ u8 *buf;
+ struct ether_header *eth;
+ struct l2_packet_data *l2 = NULL;
+ size_t len;
+ u16 ethertype;
+ int res = -1;
+ const char *ifname = hapd->conf->iface;
+
+ if (os_strncmp(cmd, "ifname=", 7) == 0) {
+ cmd += 7;
+ ifname = cmd;
+ cmd = os_strchr(cmd, ' ');
+ if (cmd == NULL)
+ return -1;
+ *cmd++ = '\0';
+ }
+
+ len = os_strlen(cmd);
+ if (len & 1 || len < ETH_HLEN * 2)
+ return -1;
+ len /= 2;
+
+ buf = os_malloc(len);
+ if (buf == NULL)
+ return -1;
+
+ if (hexstr2bin(cmd, buf, len) < 0)
+ goto done;
+
+ eth = (struct ether_header *) buf;
+ ethertype = ntohs(eth->ether_type);
+
+ l2 = l2_packet_init(ifname, hapd->own_addr, ethertype,
+ hostapd_data_test_rx, hapd, 1);
+ if (l2 == NULL)
+ goto done;
+
+ res = l2_packet_send(l2, eth->ether_dhost, ethertype, buf, len);
+ wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "test data: TX frame res=%d", res);
+done:
+ if (l2)
+ l2_packet_deinit(l2);
+ os_free(buf);
+
+ return res < 0 ? -1 : 0;
+}
+
+
+static int hostapd_ctrl_test_alloc_fail(struct hostapd_data *hapd, char *cmd)
+{
+#ifdef WPA_TRACE_BFD
+ extern char wpa_trace_fail_func[256];
+ extern unsigned int wpa_trace_fail_after;
+ char *pos;
+
+ wpa_trace_fail_after = atoi(cmd);
+ pos = os_strchr(cmd, ':');
+ if (pos) {
+ pos++;
+ os_strlcpy(wpa_trace_fail_func, pos,
+ sizeof(wpa_trace_fail_func));
+ } else {
+ wpa_trace_fail_after = 0;
+ }
+
+ return 0;
+#else /* WPA_TRACE_BFD */
+ return -1;
+#endif /* WPA_TRACE_BFD */
+}
+
+
+static int hostapd_ctrl_get_alloc_fail(struct hostapd_data *hapd,
+ char *buf, size_t buflen)
+{
+#ifdef WPA_TRACE_BFD
+ extern char wpa_trace_fail_func[256];
+ extern unsigned int wpa_trace_fail_after;
+
+ return os_snprintf(buf, buflen, "%u:%s", wpa_trace_fail_after,
+ wpa_trace_fail_func);
+#else /* WPA_TRACE_BFD */
+ return -1;
+#endif /* WPA_TRACE_BFD */
+}
+
#endif /* CONFIG_TESTING_OPTIONS */
@@ -1366,7 +1863,8 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
res = recvfrom(sock, buf, sizeof(buf) - 1, 0,
(struct sockaddr *) &from, &fromlen);
if (res < 0) {
- perror("recvfrom(ctrl_iface)");
+ wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s",
+ strerror(errno));
return;
}
buf[res] = '\0';
@@ -1376,8 +1874,11 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
reply = os_malloc(reply_size);
if (reply == NULL) {
- sendto(sock, "FAIL\n", 5, 0, (struct sockaddr *) &from,
- fromlen);
+ if (sendto(sock, "FAIL\n", 5, 0, (struct sockaddr *) &from,
+ fromlen) < 0) {
+ wpa_printf(MSG_DEBUG, "CTRL: sendto failed: %s",
+ strerror(errno));
+ }
return;
}
@@ -1455,6 +1956,9 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
} else if (os_strncmp(buf, "DISASSOCIATE ", 13) == 0) {
if (hostapd_ctrl_iface_disassociate(hapd, buf + 13))
reply_len = -1;
+ } else if (os_strcmp(buf, "STOP_AP") == 0) {
+ if (hostapd_ctrl_iface_stop_ap(hapd))
+ reply_len = -1;
#ifdef CONFIG_IEEE80211W
#ifdef NEED_AP_MLME
} else if (os_strncmp(buf, "SA_QUERY ", 9) == 0) {
@@ -1525,6 +2029,9 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
} else if (os_strncmp(buf, "ESS_DISASSOC ", 13) == 0) {
if (hostapd_ctrl_iface_ess_disassoc(hapd, buf + 13))
reply_len = -1;
+ } else if (os_strncmp(buf, "BSS_TM_REQ ", 11) == 0) {
+ if (hostapd_ctrl_iface_bss_tm_req(hapd, buf + 11))
+ reply_len = -1;
#endif /* CONFIG_WNM */
} else if (os_strcmp(buf, "GET_CONFIG") == 0) {
reply_len = hostapd_ctrl_iface_get_config(hapd, reply,
@@ -1544,6 +2051,9 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
} else if (os_strncmp(buf, "DISABLE", 7) == 0) {
if (hostapd_ctrl_iface_disable(hapd->iface))
reply_len = -1;
+ } else if (os_strcmp(buf, "UPDATE_BEACON") == 0) {
+ if (ieee802_11_set_beacon(hapd))
+ reply_len = -1;
#ifdef CONFIG_TESTING_OPTIONS
} else if (os_strncmp(buf, "RADAR ", 6) == 0) {
if (hostapd_ctrl_iface_radar(hapd, buf + 6))
@@ -1551,6 +2061,24 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
} else if (os_strncmp(buf, "MGMT_TX ", 8) == 0) {
if (hostapd_ctrl_iface_mgmt_tx(hapd, buf + 8))
reply_len = -1;
+ } else if (os_strncmp(buf, "EAPOL_RX ", 9) == 0) {
+ if (hostapd_ctrl_iface_eapol_rx(hapd, buf + 9) < 0)
+ reply_len = -1;
+ } else if (os_strncmp(buf, "DATA_TEST_CONFIG ", 17) == 0) {
+ if (hostapd_ctrl_iface_data_test_config(hapd, buf + 17) < 0)
+ reply_len = -1;
+ } else if (os_strncmp(buf, "DATA_TEST_TX ", 13) == 0) {
+ if (hostapd_ctrl_iface_data_test_tx(hapd, buf + 13) < 0)
+ reply_len = -1;
+ } else if (os_strncmp(buf, "DATA_TEST_FRAME ", 16) == 0) {
+ if (hostapd_ctrl_iface_data_test_frame(hapd, buf + 16) < 0)
+ reply_len = -1;
+ } else if (os_strncmp(buf, "TEST_ALLOC_FAIL ", 16) == 0) {
+ if (hostapd_ctrl_test_alloc_fail(hapd, buf + 16) < 0)
+ reply_len = -1;
+ } else if (os_strcmp(buf, "GET_ALLOC_FAIL") == 0) {
+ reply_len = hostapd_ctrl_get_alloc_fail(hapd, reply,
+ reply_size);
#endif /* CONFIG_TESTING_OPTIONS */
} else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) {
if (hostapd_ctrl_iface_chan_switch(hapd->iface, buf + 12))
@@ -1558,7 +2086,11 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
} else if (os_strncmp(buf, "VENDOR ", 7) == 0) {
reply_len = hostapd_ctrl_iface_vendor(hapd, buf + 7, reply,
reply_size);
-
+ } else if (os_strcmp(buf, "ERP_FLUSH") == 0) {
+ ieee802_1x_erp_flush(hapd);
+#ifdef RADIUS_SERVER
+ radius_server_erp_flush(hapd->radius_srv);
+#endif /* RADIUS_SERVER */
} else {
os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
reply_len = 16;
@@ -1568,7 +2100,11 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
os_memcpy(reply, "FAIL\n", 5);
reply_len = 5;
}
- sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from, fromlen);
+ if (sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from,
+ fromlen) < 0) {
+ wpa_printf(MSG_DEBUG, "CTRL: sendto failed: %s",
+ strerror(errno));
+ }
os_free(reply);
}
@@ -1623,7 +2159,8 @@ int hostapd_ctrl_iface_init(struct hostapd_data *hapd)
wpa_printf(MSG_DEBUG, "Using existing control "
"interface directory.");
} else {
- perror("mkdir[ctrl_interface]");
+ wpa_printf(MSG_ERROR, "mkdir[ctrl_interface]: %s",
+ strerror(errno));
goto fail;
}
}
@@ -1631,7 +2168,8 @@ int hostapd_ctrl_iface_init(struct hostapd_data *hapd)
if (hapd->conf->ctrl_interface_gid_set &&
chown(hapd->conf->ctrl_interface, -1,
hapd->conf->ctrl_interface_gid) < 0) {
- perror("chown[ctrl_interface]");
+ wpa_printf(MSG_ERROR, "chown[ctrl_interface]: %s",
+ strerror(errno));
return -1;
}
@@ -1639,7 +2177,8 @@ int hostapd_ctrl_iface_init(struct hostapd_data *hapd)
hapd->iface->interfaces->ctrl_iface_group &&
chown(hapd->conf->ctrl_interface, -1,
hapd->iface->interfaces->ctrl_iface_group) < 0) {
- perror("chown[ctrl_interface]");
+ wpa_printf(MSG_ERROR, "chown[ctrl_interface]: %s",
+ strerror(errno));
return -1;
}
@@ -1664,7 +2203,7 @@ int hostapd_ctrl_iface_init(struct hostapd_data *hapd)
s = socket(PF_UNIX, SOCK_DGRAM, 0);
if (s < 0) {
- perror("socket(PF_UNIX)");
+ wpa_printf(MSG_ERROR, "socket(PF_UNIX): %s", strerror(errno));
goto fail;
}
@@ -1685,15 +2224,16 @@ int hostapd_ctrl_iface_init(struct hostapd_data *hapd)
" allow connections - assuming it was left"
"over from forced program termination");
if (unlink(fname) < 0) {
- perror("unlink[ctrl_iface]");
- wpa_printf(MSG_ERROR, "Could not unlink "
- "existing ctrl_iface socket '%s'",
- fname);
+ wpa_printf(MSG_ERROR,
+ "Could not unlink existing ctrl_iface socket '%s': %s",
+ fname, strerror(errno));
goto fail;
}
if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) <
0) {
- perror("hostapd-ctrl-iface: bind(PF_UNIX)");
+ wpa_printf(MSG_ERROR,
+ "hostapd-ctrl-iface: bind(PF_UNIX): %s",
+ strerror(errno));
goto fail;
}
wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
@@ -1711,26 +2251,32 @@ int hostapd_ctrl_iface_init(struct hostapd_data *hapd)
if (hapd->conf->ctrl_interface_gid_set &&
chown(fname, -1, hapd->conf->ctrl_interface_gid) < 0) {
- perror("chown[ctrl_interface/ifname]");
+ wpa_printf(MSG_ERROR, "chown[ctrl_interface/ifname]: %s",
+ strerror(errno));
goto fail;
}
if (!hapd->conf->ctrl_interface_gid_set &&
hapd->iface->interfaces->ctrl_iface_group &&
chown(fname, -1, hapd->iface->interfaces->ctrl_iface_group) < 0) {
- perror("chown[ctrl_interface/ifname]");
+ wpa_printf(MSG_ERROR, "chown[ctrl_interface/ifname]: %s",
+ strerror(errno));
goto fail;
}
if (chmod(fname, S_IRWXU | S_IRWXG) < 0) {
- perror("chmod[ctrl_interface/ifname]");
+ wpa_printf(MSG_ERROR, "chmod[ctrl_interface/ifname]: %s",
+ strerror(errno));
goto fail;
}
os_free(fname);
hapd->ctrl_sock = s;
- eloop_register_read_sock(s, hostapd_ctrl_iface_receive, hapd,
- NULL);
+ if (eloop_register_read_sock(s, hostapd_ctrl_iface_receive, hapd,
+ NULL) < 0) {
+ hostapd_ctrl_iface_deinit(hapd);
+ return -1;
+ }
hapd->msg_ctx = hapd;
wpa_msg_register_cb(hostapd_ctrl_iface_msg_cb);
@@ -1777,11 +2323,17 @@ void hostapd_ctrl_iface_deinit(struct hostapd_data *hapd)
}
dst = hapd->ctrl_dst;
+ hapd->ctrl_dst = NULL;
while (dst) {
prev = dst;
dst = dst->next;
os_free(prev);
}
+
+#ifdef CONFIG_TESTING_OPTIONS
+ l2_packet_deinit(hapd->l2_test);
+ hapd->l2_test = NULL;
+#endif /* CONFIG_TESTING_OPTIONS */
}
@@ -1831,7 +2383,8 @@ static void hostapd_global_ctrl_iface_receive(int sock, void *eloop_ctx,
res = recvfrom(sock, buf, sizeof(buf) - 1, 0,
(struct sockaddr *) &from, &fromlen);
if (res < 0) {
- perror("recvfrom(ctrl_iface)");
+ wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s",
+ strerror(errno));
return;
}
buf[res] = '\0';
@@ -1871,7 +2424,11 @@ static void hostapd_global_ctrl_iface_receive(int sock, void *eloop_ctx,
reply_len = 5;
}
- sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from, fromlen);
+ if (sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from,
+ fromlen) < 0) {
+ wpa_printf(MSG_DEBUG, "CTRL: sendto failed: %s",
+ strerror(errno));
+ }
}
@@ -1912,13 +2469,15 @@ int hostapd_global_ctrl_iface_init(struct hapd_interfaces *interface)
wpa_printf(MSG_DEBUG, "Using existing control "
"interface directory.");
} else {
- perror("mkdir[ctrl_interface]");
+ wpa_printf(MSG_ERROR, "mkdir[ctrl_interface]: %s",
+ strerror(errno));
goto fail;
}
} else if (interface->ctrl_iface_group &&
chown(interface->global_iface_path, -1,
interface->ctrl_iface_group) < 0) {
- perror("chown[ctrl_interface]");
+ wpa_printf(MSG_ERROR, "chown[ctrl_interface]: %s",
+ strerror(errno));
goto fail;
}
@@ -1928,7 +2487,7 @@ int hostapd_global_ctrl_iface_init(struct hapd_interfaces *interface)
s = socket(PF_UNIX, SOCK_DGRAM, 0);
if (s < 0) {
- perror("socket(PF_UNIX)");
+ wpa_printf(MSG_ERROR, "socket(PF_UNIX): %s", strerror(errno));
goto fail;
}
@@ -1949,15 +2508,15 @@ int hostapd_global_ctrl_iface_init(struct hapd_interfaces *interface)
" allow connections - assuming it was left"
"over from forced program termination");
if (unlink(fname) < 0) {
- perror("unlink[ctrl_iface]");
- wpa_printf(MSG_ERROR, "Could not unlink "
- "existing ctrl_iface socket '%s'",
- fname);
+ wpa_printf(MSG_ERROR,
+ "Could not unlink existing ctrl_iface socket '%s': %s",
+ fname, strerror(errno));
goto fail;
}
if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) <
0) {
- perror("bind(PF_UNIX)");
+ wpa_printf(MSG_ERROR, "bind(PF_UNIX): %s",
+ strerror(errno));
goto fail;
}
wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
@@ -1975,12 +2534,14 @@ int hostapd_global_ctrl_iface_init(struct hapd_interfaces *interface)
if (interface->ctrl_iface_group &&
chown(fname, -1, interface->ctrl_iface_group) < 0) {
- perror("chown[ctrl_interface]");
+ wpa_printf(MSG_ERROR, "chown[ctrl_interface]: %s",
+ strerror(errno));
goto fail;
}
if (chmod(fname, S_IRWXU | S_IRWXG) < 0) {
- perror("chmod[ctrl_interface/ifname]");
+ wpa_printf(MSG_ERROR, "chmod[ctrl_interface/ifname]: %s",
+ strerror(errno));
goto fail;
}
os_free(fname);
diff --git a/hostapd/defconfig b/hostapd/defconfig
index 5b74b64..4cde2b5 100644
--- a/hostapd/defconfig
+++ b/hostapd/defconfig
@@ -15,10 +15,6 @@ CONFIG_DRIVER_HOSTAP=y
# Driver interface for wired authenticator
#CONFIG_DRIVER_WIRED=y
-# Driver interface for madwifi driver
-#CONFIG_DRIVER_MADWIFI=y
-#CFLAGS += -I../../madwifi # change to the madwifi source directory
-
# Driver interface for drivers using the nl80211 kernel interface
CONFIG_DRIVER_NL80211=y
@@ -60,6 +56,9 @@ CONFIG_IEEE80211W=y
# Integrated EAP server
CONFIG_EAP=y
+# EAP Re-authentication Protocol (ERP) in integrated EAP server
+CONFIG_ERP=y
+
# EAP-MD5 for the integrated EAP server
CONFIG_EAP_MD5=y
@@ -142,7 +141,7 @@ CONFIG_IPV6=y
#CONFIG_IEEE80211R=y
# Use the hostapd's IEEE 802.11 authentication (ACL), but without
-# the IEEE 802.11 Management capability (e.g., madwifi or FreeBSD/net80211)
+# the IEEE 802.11 Management capability (e.g., FreeBSD/net80211)
#CONFIG_DRIVER_RADIUS_ACL=y
# IEEE 802.11n (High Throughput) support
diff --git a/hostapd/hlr_auc_gw.c b/hostapd/hlr_auc_gw.c
index c041887..42d59db 100644
--- a/hostapd/hlr_auc_gw.c
+++ b/hostapd/hlr_auc_gw.c
@@ -711,7 +711,7 @@ static int gsm_auth_req(char *imsi, char *resp, size_t resp_len)
rend = resp + resp_len;
rpos = resp;
ret = os_snprintf(rpos, rend - rpos, "GSM-AUTH-RESP %s", imsi);
- if (ret < 0 || ret >= rend - rpos)
+ if (os_snprintf_error(rend - rpos, ret))
return -1;
rpos += ret;
@@ -737,7 +737,7 @@ static int gsm_auth_req(char *imsi, char *resp, size_t resp_len)
printf("No GSM triplets found for %s\n", imsi);
ret = os_snprintf(rpos, rend - rpos, " FAILURE");
- if (ret < 0 || ret >= rend - rpos)
+ if (os_snprintf_error(rend - rpos, ret))
return -1;
rpos += ret;
diff --git a/hostapd/hostapd.8 b/hostapd/hostapd.8
index b4456bb..d19d862 100644
--- a/hostapd/hostapd.8
+++ b/hostapd/hostapd.8
@@ -12,7 +12,7 @@ daemon.
.B hostapd
is a user space daemon for access point and authentication servers.
It implements IEEE 802.11 access point management, IEEE 802.1X/WPA/WPA2/EAP Authenticators and RADIUS authentication server.
-The current version supports Linux (Host AP, madwifi, mac80211-based drivers) and FreeBSD (net80211).
+The current version supports Linux (Host AP, mac80211-based drivers) and FreeBSD (net80211).
.B hostapd
is designed to be a "daemon" program that runs in the background and acts as the backend component controlling authentication.
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index a7ab0f6..9e81e9e 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -2,10 +2,10 @@
# Empty lines and lines starting with # are ignored
# AP netdevice name (without 'ap' postfix, i.e., wlan0 uses wlan0ap for
-# management frames); ath0 for madwifi
+# management frames with the Host AP driver); wlan0 with many nl80211 drivers
interface=wlan0
-# In case of madwifi, atheros, and nl80211 driver interfaces, an additional
+# In case of atheros and nl80211 driver interfaces, an additional
# configuration parameter, bridge, may be used to notify hostapd if the
# interface is included in a bridge. This parameter is not used with Host AP
# driver. If the bridge parameter is not set, the drivers will automatically
@@ -18,12 +18,15 @@ interface=wlan0
# interface is also created.
#bridge=br0
-# Driver interface type (hostap/wired/madwifi/test/none/nl80211/bsd);
+# Driver interface type (hostap/wired/none/nl80211/bsd);
# default: hostap). nl80211 is used with all Linux mac80211 drivers.
# Use driver=none if building hostapd as a standalone RADIUS server that does
# not control any wireless/wired driver.
# driver=hostap
+# Driver interface parameters (mainly for development testing use)
+# driver_params=<params>
+
# hostapd event logger configuration
#
# Two output method: syslog and stdout (only usable if not forking to
@@ -151,14 +154,22 @@ channel=1
# interference that may help choosing a better channel. This can also help fine
# tune the ACS scan time in case a driver has different scan dwell times.
#
+# acs_chan_bias is a space-separated list of <channel>:<bias> pairs. It can be
+# used to increase (or decrease) the likelihood of a specific channel to be
+# selected by the ACS algorithm. The total interference factor for each channel
+# gets multiplied by the specified bias value before finding the channel with
+# the lowest value. In other words, values between 0.0 and 1.0 can be used to
+# make a channel more likely to be picked while values larger than 1.0 make the
+# specified channel less likely to be picked. This can be used, e.g., to prefer
+# the commonly used 2.4 GHz band channels 1, 6, and 11 (which is the default
+# behavior on 2.4 GHz band if no acs_chan_bias parameter is specified).
+#
# Defaults:
#acs_num_scans=5
+#acs_chan_bias=1:0.8 6:0.8 11:0.8
# Channel list restriction. This option allows hostapd to select one of the
-# provided channels when a channel should be automatically selected. This
-# is currently only used for DFS when the current channels becomes unavailable
-# due to radar interference, and is currently only useful when ieee80211h=1 is
-# set.
+# provided channels when a channel should be automatically selected.
# Default: not set (allow any enabled channel to be selected)
#chanlist=100 104 108 112 116
@@ -221,7 +232,7 @@ fragm_threshold=2346
# Station MAC address -based authentication
# Please note that this kind of access control requires a driver that uses
# hostapd to take care of management frame processing and as such, this can be
-# used with driver=hostap or driver=nl80211, but not with driver=madwifi.
+# used with driver=hostap or driver=nl80211, but not with driver=atheros.
# 0 = accept unless in deny list
# 1 = deny unless in accept list
# 2 = use external RADIUS server (accept/deny lists are searched first)
@@ -435,6 +446,11 @@ wmm_ac_vo_acm=0
# associated stations in the BSS. By default, this bridging is allowed.
#ap_isolate=1
+# BSS Load update period (in BUs)
+# This field is used to enable and configure adding a BSS Load element into
+# Beacon and Probe Response frames.
+#bss_load_update_period=50
+
# Fixed BSS Load value for testing purposes
# This field can be used to configure hostapd to add a fixed BSS Load element
# into Beacon and Probe Response frames for testing purposes. The format is
@@ -489,9 +505,9 @@ wmm_ac_vo_acm=0
# If set non-zero, require stations to perform scans of overlapping
# channels to test for stations which would be affected by 40 MHz traffic.
-# This parameter sets the interval in seconds between these scans. This
-# is useful only for testing that stations properly set the OBSS interval,
-# since the other parameters in the OBSS scan parameters IE are set to 0.
+# This parameter sets the interval in seconds between these scans. Setting this
+# to non-zero allows 2.4 GHz band AP to move dynamically to a 40 MHz channel if
+# no co-existence issues with neighboring devices are found.
#obss_interval=0
##### IEEE 802.11ac related configuration #####################################
@@ -688,6 +704,17 @@ eapol_key_index_workaround=0
# is only used by one station.
#use_pae_group_addr=1
+# EAP Re-authentication Protocol (ERP) authenticator (RFC 6696)
+#
+# Whether to initiate EAP authentication with EAP-Initiate/Re-auth-Start before
+# EAP-Identity/Request
+#erp_send_reauth_start=1
+#
+# Domain name for EAP-Initiate/Re-auth-Start. Omitted from the message if not
+# set (no local ER server). This is also used by the integrated EAP server if
+# ERP is enabled (eap_server_erp=1).
+#erp_domain=example.com
+
##### Integrated EAP server ###################################################
# Optionally, hostapd can be configured to use an integrated EAP server
@@ -763,6 +790,15 @@ eap_server=0
# "openssl dhparam -out /etc/hostapd.dh.pem 1024"
#dh_file=/etc/hostapd.dh.pem
+# OpenSSL cipher string
+#
+# This is an OpenSSL specific configuration option for configuring the default
+# ciphers. If not set, "DEFAULT:!EXP:!LOW" is used as the default.
+# See https://www.openssl.org/docs/apps/ciphers.html for OpenSSL documentation
+# on cipher suite configuration. This is applicable only if hostapd is built to
+# use OpenSSL.
+#openssl_ciphers=DEFAULT:!EXP:!LOW
+
# Fragment size for EAP methods
#fragment_size=1400
@@ -824,6 +860,10 @@ eap_server=0
# EAP method is enabled, the peer will be allowed to connect without TNC.
#tnc=1
+# EAP Re-authentication Protocol (ERP) - RFC 6696
+#
+# Whether to enable ERP on the EAP server.
+#eap_server_erp=1
##### IEEE 802.11f - Inter-Access Point Protocol (IAPP) #######################
@@ -845,6 +885,12 @@ own_ip_addr=127.0.0.1
# 48 octets long.
#nas_identifier=ap.example.com
+# RADIUS client forced local IP address for the access point
+# Normally the local IP address is determined automatically based on configured
+# IP addresses, but this field can be used to force a specific address to be
+# used, e.g., when the device has multiple IP addresses.
+#radius_client_addr=127.0.0.1
+
# RADIUS authentication server
#auth_server_addr=127.0.0.1
#auth_server_port=1812
@@ -1439,6 +1485,11 @@ own_ip_addr=127.0.0.1
# 1 = enabled
#bss_transition=1
+# Proxy ARP
+# 0 = disabled (default)
+# 1 = enabled
+#proxy_arp=1
+
##### IEEE 802.11u-2011 #######################################################
# Enable Interworking service
diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
index 9e62bef..3f00cbb 100644
--- a/hostapd/hostapd_cli.c
+++ b/hostapd/hostapd_cli.c
@@ -1,6 +1,6 @@
/*
* hostapd - command line interface for hostapd daemon
- * Copyright (c) 2004-2014, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -18,7 +18,7 @@
static const char *hostapd_cli_version =
"hostapd_cli v" VERSION_STR "\n"
-"Copyright (c) 2004-2014, Jouni Malinen <j@w1.fi> and contributors";
+"Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi> and contributors";
static const char *hostapd_cli_license =
@@ -393,7 +393,7 @@ static int hostapd_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
else
res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s",
argv[0]);
- if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
+ if (os_snprintf_error(sizeof(cmd), res)) {
printf("Too long WPS_CHECK_PIN command.\n");
return -1;
}
@@ -456,7 +456,7 @@ static int hostapd_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl,
res = os_snprintf(cmd, sizeof(cmd), "WPS_NFC_CONFIG_TOKEN %s",
argv[0]);
- if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
+ if (os_snprintf_error(sizeof(cmd), res)) {
printf("Too long WPS_NFC_CONFIG_TOKEN command.\n");
return -1;
}
@@ -477,7 +477,7 @@ static int hostapd_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl,
}
res = os_snprintf(cmd, sizeof(cmd), "WPS_NFC_TOKEN %s", argv[0]);
- if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
+ if (os_snprintf_error(sizeof(cmd), res)) {
printf("Too long WPS_NFC_TOKEN command.\n");
return -1;
}
@@ -499,7 +499,7 @@ static int hostapd_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl,
res = os_snprintf(cmd, sizeof(cmd), "NFC_GET_HANDOVER_SEL %s %s",
argv[0], argv[1]);
- if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
+ if (os_snprintf_error(sizeof(cmd), res)) {
printf("Too long NFC_GET_HANDOVER_SEL command.\n");
return -1;
}
@@ -596,7 +596,7 @@ static int hostapd_cli_cmd_disassoc_imminent(struct wpa_ctrl *ctrl, int argc,
res = os_snprintf(buf, sizeof(buf), "DISASSOC_IMMINENT %s %s",
argv[0], argv[1]);
- if (res < 0 || res >= (int) sizeof(buf))
+ if (os_snprintf_error(sizeof(buf), res))
return -1;
return wpa_ctrl_command(ctrl, buf);
}
@@ -616,12 +616,39 @@ static int hostapd_cli_cmd_ess_disassoc(struct wpa_ctrl *ctrl, int argc,
res = os_snprintf(buf, sizeof(buf), "ESS_DISASSOC %s %s %s",
argv[0], argv[1], argv[2]);
- if (res < 0 || res >= (int) sizeof(buf))
+ if (os_snprintf_error(sizeof(buf), res))
return -1;
return wpa_ctrl_command(ctrl, buf);
}
+static int hostapd_cli_cmd_bss_tm_req(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ char buf[2000], *tmp;
+ int res, i, total;
+
+ if (argc < 1) {
+ printf("Invalid 'bss_tm_req' command - at least one argument (STA addr) is needed\n");
+ return -1;
+ }
+
+ res = os_snprintf(buf, sizeof(buf), "BSS_TM_REQ %s", argv[0]);
+ if (os_snprintf_error(sizeof(buf), res))
+ return -1;
+
+ total = res;
+ for (i = 1; i < argc; i++) {
+ tmp = &buf[total];
+ res = os_snprintf(tmp, sizeof(buf) - total, " %s", argv[i]);
+ if (os_snprintf_error(sizeof(buf) - total, res))
+ return -1;
+ total += res;
+ }
+ return wpa_ctrl_command(ctrl, buf);
+}
+
+
static int hostapd_cli_cmd_get_config(struct wpa_ctrl *ctrl, int argc,
char *argv[])
{
@@ -709,7 +736,7 @@ static int hostapd_cli_cmd_set_qos_map_set(struct wpa_ctrl *ctrl,
}
res = os_snprintf(buf, sizeof(buf), "SET_QOS_MAP_SET %s", argv[0]);
- if (res < 0 || res >= (int) sizeof(buf))
+ if (os_snprintf_error(sizeof(buf), res))
return -1;
return wpa_ctrl_command(ctrl, buf);
}
@@ -728,7 +755,7 @@ static int hostapd_cli_cmd_send_qos_map_conf(struct wpa_ctrl *ctrl,
}
res = os_snprintf(buf, sizeof(buf), "SEND_QOS_MAP_CONF %s", argv[0]);
- if (res < 0 || res >= (int) sizeof(buf))
+ if (os_snprintf_error(sizeof(buf), res))
return -1;
return wpa_ctrl_command(ctrl, buf);
}
@@ -748,7 +775,7 @@ static int hostapd_cli_cmd_hs20_wnm_notif(struct wpa_ctrl *ctrl, int argc,
res = os_snprintf(buf, sizeof(buf), "HS20_WNM_NOTIF %s %s",
argv[0], argv[1]);
- if (res < 0 || res >= (int) sizeof(buf))
+ if (os_snprintf_error(sizeof(buf), res))
return -1;
return wpa_ctrl_command(ctrl, buf);
}
@@ -773,7 +800,7 @@ static int hostapd_cli_cmd_hs20_deauth_req(struct wpa_ctrl *ctrl, int argc,
res = os_snprintf(buf, sizeof(buf),
"HS20_DEAUTH_REQ %s %s %s",
argv[0], argv[1], argv[2]);
- if (res < 0 || res >= (int) sizeof(buf))
+ if (os_snprintf_error(sizeof(buf), res))
return -1;
return wpa_ctrl_command(ctrl, buf);
}
@@ -866,7 +893,7 @@ static int hostapd_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
}
res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
- if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
+ if (os_snprintf_error(sizeof(cmd), res)) {
printf("Too long SET command.\n");
return -1;
}
@@ -886,7 +913,7 @@ static int hostapd_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
}
res = os_snprintf(cmd, sizeof(cmd), "GET %s", argv[0]);
- if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
+ if (os_snprintf_error(sizeof(cmd), res)) {
printf("Too long GET command.\n");
return -1;
}
@@ -914,7 +941,7 @@ static int hostapd_cli_cmd_chan_switch(struct wpa_ctrl *ctrl,
res = os_snprintf(cmd, sizeof(cmd), "CHAN_SWITCH %s %s",
argv[0], argv[1]);
- if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
+ if (os_snprintf_error(sizeof(cmd), res)) {
printf("Too long CHAN_SWITCH command.\n");
return -1;
}
@@ -923,7 +950,7 @@ static int hostapd_cli_cmd_chan_switch(struct wpa_ctrl *ctrl,
for (i = 2; i < argc; i++) {
tmp = cmd + total;
res = os_snprintf(tmp, sizeof(cmd) - total, " %s", argv[i]);
- if (res < 0 || (size_t) res >= sizeof(cmd) - total - 1) {
+ if (os_snprintf_error(sizeof(cmd) - total, res)) {
printf("Too long CHAN_SWITCH command.\n");
return -1;
}
@@ -933,6 +960,27 @@ static int hostapd_cli_cmd_chan_switch(struct wpa_ctrl *ctrl,
}
+static int hostapd_cli_cmd_enable(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ return wpa_ctrl_command(ctrl, "ENABLE");
+}
+
+
+static int hostapd_cli_cmd_reload(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ return wpa_ctrl_command(ctrl, "RELOAD");
+}
+
+
+static int hostapd_cli_cmd_disable(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ return wpa_ctrl_command(ctrl, "DISABLE");
+}
+
+
static int hostapd_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[])
{
char cmd[256];
@@ -946,7 +994,7 @@ static int hostapd_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[])
res = os_snprintf(cmd, sizeof(cmd), "VENDOR %s %s %s", argv[0], argv[1],
argc == 3 ? argv[2] : "");
- if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
+ if (os_snprintf_error(sizeof(cmd), res)) {
printf("Too long VENDOR command.\n");
return -1;
}
@@ -954,6 +1002,13 @@ static int hostapd_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[])
}
+static int hostapd_cli_cmd_erp_flush(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ return wpa_ctrl_command(ctrl, "ERP_FLUSH");
+}
+
+
struct hostapd_cli_cmd {
const char *cmd;
int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
@@ -989,6 +1044,7 @@ static struct hostapd_cli_cmd hostapd_cli_commands[] = {
#endif /* CONFIG_WPS */
{ "disassoc_imminent", hostapd_cli_cmd_disassoc_imminent },
{ "ess_disassoc", hostapd_cli_cmd_ess_disassoc },
+ { "bss_tm_req", hostapd_cli_cmd_bss_tm_req },
{ "get_config", hostapd_cli_cmd_get_config },
{ "help", hostapd_cli_cmd_help },
{ "interface", hostapd_cli_cmd_interface },
@@ -1003,6 +1059,10 @@ static struct hostapd_cli_cmd hostapd_cli_commands[] = {
{ "hs20_wnm_notif", hostapd_cli_cmd_hs20_wnm_notif },
{ "hs20_deauth_req", hostapd_cli_cmd_hs20_deauth_req },
{ "vendor", hostapd_cli_cmd_vendor },
+ { "enable", hostapd_cli_cmd_enable },
+ { "reload", hostapd_cli_cmd_reload },
+ { "disable", hostapd_cli_cmd_disable },
+ { "erp_flush", hostapd_cli_cmd_erp_flush },
{ NULL, NULL }
};
diff --git a/hostapd/main.c b/hostapd/main.c
index a9d91b9..dd389a8 100644
--- a/hostapd/main.c
+++ b/hostapd/main.c
@@ -1,6 +1,6 @@
/*
* hostapd / main()
- * Copyright (c) 2002-2011, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2002-2015, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -184,9 +184,7 @@ static int hostapd_driver_init(struct hostapd_iface *iface)
}
params.bssid = b;
params.ifname = hapd->conf->iface;
- params.ssid = hapd->conf->ssid.ssid;
- params.ssid_len = hapd->conf->ssid.ssid_len;
- params.test_socket = hapd->conf->test_socket;
+ params.driver_params = hapd->iconf->driver_params;
params.use_pae_group_addr = hapd->conf->use_pae_group_addr;
params.num_bridge = hapd->iface->num_bss;
@@ -212,12 +210,22 @@ static int hostapd_driver_init(struct hostapd_iface *iface)
if (hapd->driver->get_capa &&
hapd->driver->get_capa(hapd->drv_priv, &capa) == 0) {
+ struct wowlan_triggers *triggs;
+
iface->drv_flags = capa.flags;
+ iface->smps_modes = capa.smps_modes;
iface->probe_resp_offloads = capa.probe_resp_offloads;
iface->extended_capa = capa.extended_capa;
iface->extended_capa_mask = capa.extended_capa_mask;
iface->extended_capa_len = capa.extended_capa_len;
iface->drv_max_acl_mac_addrs = capa.max_acl_mac_addrs;
+
+ triggs = wpa_get_wowlan_triggers(conf->wowlan_triggers, &capa);
+ if (triggs && hapd->driver->set_wowlan) {
+ if (hapd->driver->set_wowlan(hapd->drv_priv, triggs))
+ wpa_printf(MSG_ERROR, "set_wowlan failed");
+ }
+ os_free(triggs);
}
return 0;
@@ -400,7 +408,7 @@ static int hostapd_global_run(struct hapd_interfaces *ifaces, int daemonize,
#endif /* EAP_SERVER_TNC */
if (daemonize && os_daemonize(pid_file)) {
- perror("daemon");
+ wpa_printf(MSG_ERROR, "daemon: %s", strerror(errno));
return -1;
}
@@ -416,7 +424,7 @@ static void show_version(void)
"hostapd v" VERSION_STR "\n"
"User space daemon for IEEE 802.11 AP management,\n"
"IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator\n"
- "Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi> "
+ "Copyright (c) 2002-2015, Jouni Malinen <j@w1.fi> "
"and contributors\n");
}
@@ -630,6 +638,8 @@ int main(int argc, char *argv[])
if (log_file)
wpa_debug_open_file(log_file);
+ else
+ wpa_debug_setup_stdout();
#ifdef CONFIG_DEBUG_LINUX_TRACING
if (enable_trace_dbg) {
int tret = wpa_debug_open_linux_tracing();