Cumulative patch from commit 95fb2db2420d8fa291fd6423cc6dbcd042f4eb46
95fb2db P2P: Reject group formation on WPS provisioning failure
6fc61e1 Fix TX status processing during AP mode shutdown in wpa_supplicant
90a545c nl80211: Clean up netlink parsing and debug prints
b6a9590 Interworking: Keep up to two pending GAS_REQUEST responses
090b8e3 Update copyright notices for the new year 2014
991aa9c nl80211: Move CS supported flag to wpa_driver_capa
f0cbb98 Add DRIVER-STATUS command for hostapd
188ebcd EAP-IKEv2 peer: Fix a memory leak in notify round
a190189 Remove PEAPv2 support
16a19dd EAP-pwd peer: Allow fragmentation limit to be configured
60bf585 EAP-IKEv2 peer: Allow fragmentation limit to be configured
ea6fc58 WPS: Convert printf() debug print to use wpa_printf()
c4b8c71 EAP-GPSK: Report CSuite negotiation failure properly
5a0f596 EAP-GPSK: Allow forced algorithm selection to be configured
5f01c3c EAP peer: Improve failure reporting from METHOD with no eapRespData
7271ee8 Fix EAP-GPSK server compilation for SHA256 cipher suite
356d148 Interworking: Add optional freq argument to INTERWORKING_SELECT
a09ffd5 Fix req_scan-deplete-timeout and update eloop API for this
083916c P2P: Clear p2p_disabled and p2p_per_sta_psk on FLUSH command
3f45fc4 P2P: Clear services on FLUSH command
1f965e6 Allow external programs to request wpa_radio work items
6428d0a Do not start wpa_radio work during externally triggered scan
6470f47 Remove unneeded scan delay on connection-in-progress
4bb2321 Remove unneeded GAS query delay on connection-in-progress
6ac4b15 Use wpa_radio work for connection
b9e6d70 Use radio work for GAS requests
e05e130 P2P: Use radio work to protect offchannel Action frame exchanges
e1d1c8e Use radio work for P2P Listen requests
1b5d471 Use radio work for P2P scan requests
d12a51b Use radio work for scan requests
b1ae396 Add framework for exclusive radio operations
dd43aaa Add helper functions for cloning and freeing scan parameters
06f9acc Ignore externally triggered scan results with scan_res_handler
c9b5559 Clean up ctrl_iface debug prints for monitor events
d31b5ac Use cleaner debug print for ctrl_iface commands with private info
9595151 Remove duplicated RX ctrl_iface hexdump
9b85079 Fix scan-cache-clearing operation to avoid unnecessary cases
2f30cac Avoid unnecessary key clearing operations
466bcf9 Remove some unnecessary EAPOL port (un)authorized callbacks
949938a Ask driver to report only new scan results if requested
a1a31b6 Remove hostapd dump_file functionality
ea23df6 Make EAPOL dump data available through ctrl_iface STA command
96ea74b Convert EAPOL authenticator dump into easier to parse format
ca3b71c Remove hostapd dump_file data that is available through ctrl_iface
4c03a2b Make RADIUS server MIB available through control interface
f538be3 Add more STA information into the ctrl_iface STA command
101bdc2 Remove forgotten notes about already removed driver wrappers
7006753 Update EAP-FAST note regarding OpenSSL support
17b79e6 nl80211: Initial support for vendor commands and events
5890fa8 WPS: Fix clear-from-timeout handling to avoid race condition
c64e3a0 P2P: Send received Presence Response information to ctrl_iface monitors
f7fb676 ACS: Mark acs_fail() static
3cf06c9 OpenSSL: Include sha1/sha256 header files to verify declarations
5ace51a WNM: Clean up le16 variable use to avoid sparse warnings
c583868 Mark wpas_wps_er_nfc_handover_sel() static
8cf1e68 Move declaration of hostapd_acs_completed() into correct header file
0187c41 Declare wpa_debug_* variables in src/utils/wpa_debug.h
fcc6123 Declare wpa_drivers in src/drivers/driver.h
0d79b50 Clear EAPOL Logoff state on FLUSH command
327b01d nl80211: Add driver param for forcing monitor and connect APIs
6f06766 nl80211: Fix nl_mgmt handling in partial error case
4ea6a47 nl80211: Prefer newer scan result over older during duplicate removal
2eef517 nl80211: Report set_supp_port failures in debug log
a0bdd19 nl80211: Share a helper function for connect and associate commands
e00d546 Remove unnecessary build #ifdef from definitions
4848a38 Get rid of duplicated cipher suite and AKM definitions
de4ed4a nl80211: Use helper functions for cipher suite mapping
a565084 nl80211: Set control port for NL80211_CMD_COMMAND
ef93abd WPS: Clean up UUID debug print
35f3d3e nl80211: Clean up regulatory rule debug prints
880de88 nl80211: Print frame registration match on same debug line
03ed332 Interworking: Allow cred blocks not to be saved to a file
04f7ecc Reset WPA parameters to default values on FLUSH command
152cff6 P2P: Remove WPA_DRIVER_FLAGS_P2P_MGMT option
538d6f4 WPS: Use shorter scan interval during pre-provisioning search
3187fd9 WPS: Replace wpas_wps_in_progress with identical wpas_wps_searching
4414d9e SAE: Fix ECC element y coordinate validation step
069fb47 EAP-EKE: Allow forced algorithm selection to be configured
3a88914 Remove unused information element parsing data
dbfb8e8 Remove unnecessary EVENT_RX_ACTION
1450e1e Define __maybe_unused
912b34f Do not process Action frames twice in hostapd SME/MLME
006309b Fix whitespace style
6780713 WPS: Remove unused send_wpabuf()
e912986 tests: Verify concurrent WPS protocol run with assigned PIN
8aaafce Make local UUID available through ctrl_iface STATUS command
0e22b8d WPS: Make sure reconfiguration timeout is not left behind on deinit
75d1d0f WPS: Allow testing mode to disable 2.0 functionality
f7e2542 Remove unused wps_device_data_dup()
c89d9db Remove unnecessary extra tracking of eloop registration
c86bf16 Replace unnecessary hex_value() with hex2byte()
7b02375 Clear wps_fragment_size on FLUSH command
aa189ac Enable FT with SAE
2d2ecf5 nl80211: Fix protected Action frame reporting for AP mode
db76aa6 Fix PeerKey 4-way handshake
7732729 Fix PeerKey deinit behavior
8d321a7 WNM: Move disassociation imminent sending to wnm_ap.c
b76f4c2 hostapd: Make STA flags available through ctrl_iface STA command
aa03dbd Remove IEEE80211_REQUIRE_AUTH_ACK
121f2ab Remove unused STA flags
3578e66 WNM: Add STA flag to indicate the current WNM-Sleep-Mode state
4776897 WNM: Fix AP processing without wnm_oper driver callback
2025cad WNM: Move ESS Disassoc Imminent sending to a helper function
28ab64a WNM: Minimal processing of BSS Transition Management Query/Response
2cd0f6a WNM: Add Target BSSID into BSS Transition Management Response
a8a6a35 WNM: Use nonzero dialog token in BSS Transition Management Query
629edfe WNM: Fix Sleep Mode AP processing in open network
3c1060f WNM: Add debug logs to get the RSSI from the scan results
dff1e28 Initial handling of GTK-not-used cipher suite
51e3eaf OpenSSL: Do not accept SSL Client certificate for server
6bf61fb OpenSSL: Use certificates from TLS authentication in OCSP stapling
c962947 WPS ER: Fix deinit timeout handling with delayed/failing unsubscribe
7b75c30 WPS: Reschedule AP configuration reload on EAP completion
c511b32 WPS: Remove old duplicate network even if key is different
9d2cb3e Make CONFIG_TESTING_OPTIONS=y enable all testing options
662b40b WPS: Reduce scan wait time during WPS processing
015af91 Do not use results from externally requested scan for network selection
1cd93ff Reschedule own scan request if an externally started one is in progress
dc3906c Show timing information about scan requests in debug log
d81c73b Optional scan id for ctrl_iface SCAN requests
a5f40ef Track whether scan was started by us or an external program
18ae237 Fix comment format
88c2d48 Allow passive scan to be requested with SCAN passive=1
3ae3ec2 nl80211: Add scanned frequencies/SSIDs into debug log
69278f7 Remove unused last_scan_full
1f5d2dd Interworking: Allow EAP-FAST to be used
6ffa168 Add GAS-QUERY-START and GAS-QUERY-DONE event messages
93827f4 hostapd: Allow external management frame processing or testing
fee5234 Allow channel list to be specified for SCAN command
98eda9c Move int_array helpfer functions to utils/common.c
a4cfb48 Add make lcov-html to generate code coverage report
bee25cc nl80211: Fetch cipher capabilities from the driver
4daa011 Clean up cipher capability prints
35c2006 Convert wpa_hexdump functions to use void pointer instead of u8 *
5f9c134 Remove obsolete license notifications
bd1e328 Android: Remove old WEXT extensions
bad5cdf Verify that beacon setup succeeds before proceeding
7d7f7be Verify group key configuration for WPA group
30675c3 Add definitions for new cipher suites from IEEE Std 802.11ac-2013
13b24a7 VHT: Use status code 104 to indicate VHT required
ab41595 wpa_supplicant: Fix crash when terminating all interfaces
76aab03 Add secondary channel IE for CSA
8f4713c Store entire CS freq_params and not only freq
13daed5 Include driver.h in hostapd.h
a12d345 wpa_supplicant: Use monotonic time for last_scan check
51bffab WPS: Use monotonic time for AP connection attempt
6473e5c wpa_supplicant: Use relative time for TKIP Michael MIC failures
4e1eae1 wpa_supplicant: Use monotonic time for temp-disabled networks
151ab80 P2P: Use monotonic time for GO client waiting
3326f19 IBSS RSN: Use monotonic time for reinit detection
196a217 WPS_UPNP: Use monotonic time for event debouncing
864c9af wps_registrar: Use monotonic time for PBC workaround
61e98e9 wps_registrar: Use monotonic time for PBC session timeout
3647e5a wps_registrar: Use monotonic time for PIN timeout
3618618 rsn_supp: Use monotonic time for PMKSA cache expiry
c2be937 wpa_supplicant: Use monotonic time for EAPOL RX workaround
e72a001 bgscan: Use monotonic time
e05f060 rsn_supp: Do not track expiration time
5870717 RADIUS server: Use monotonic time
4012804 RADIUS client: Use monotonic time
acb69ce wpa_supplicant: Use monotonic time for RX/BSS times
46b8d4c wpa_supplicant: Use monotonic time for SA query timeout
f073fde EAP server: Remove SIM-DB pending timestamp
636e19a wpa_ctrl: Use monotonic time for request retry loop
7ffe7d2 AP: Use monotonic time for MMIC failure/TKIP countermeasures
dd4e32b AP: Use monotonic time for PMKSA cache
0fc545a AP: Use monotonic time for STA accounting
3e06180 bgscan_learn: Start scanning from the first freq
f4c73ae bgscan_learn: Fix initial interval
7dab119 bgscan_learn: Avoid redundant frequencies
3727123 bgscan: Stop bgscan only on disassociation
b2838ba Update IBSS documentation to include RSN option
429dd9a Advertise QoS Map support based on driver capability
049105b nl80211: Add support for QoS Map configuration
74ddd64 nl80211: Sync with mac80211-next.git
9fcd300 nl80211: Sync with wireless-testing.git
Change-Id: Iabdd88d9cabd478a41c3cb0a8d061b425cc1beca
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/drivers/android_drv.h b/src/drivers/android_drv.h
index 5906527..31d9440 100644
--- a/src/drivers/android_drv.h
+++ b/src/drivers/android_drv.h
@@ -1,12 +1,8 @@
/*
* Android driver interface
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
*/
#ifndef ANDROID_DRV_H
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index a3602ed..db34ed1 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -1,6 +1,6 @@
/*
* Driver interface definition
- * Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2014, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -233,7 +233,7 @@
struct wpa_scan_results {
struct wpa_scan_res **res;
size_t num;
- struct os_time fetch_time;
+ struct os_reltime fetch_time;
};
/**
@@ -340,6 +340,21 @@
* and not to transmit the frames at any of those rates.
*/
u8 p2p_probe;
+
+ /**
+ * only_new_results - Request driver to report only new results
+ *
+ * This is used to request the driver to report only BSSes that have
+ * been detected after this scan request has been started, i.e., to
+ * flush old cached BSS entries.
+ */
+ int only_new_results;
+
+ /*
+ * NOTE: Whenever adding new parameters here, please make sure
+ * wpa_scan_clone_params() and wpa_scan_free_params() get updated with
+ * matching changes.
+ */
};
/**
@@ -442,25 +457,25 @@
unsigned int wpa_proto;
/**
- * pairwise_suite - Selected pairwise cipher suite
+ * pairwise_suite - Selected pairwise cipher suite (WPA_CIPHER_*)
*
* This is usually ignored if @wpa_ie is used.
*/
- enum wpa_cipher pairwise_suite;
+ unsigned int pairwise_suite;
/**
- * group_suite - Selected group cipher suite
+ * group_suite - Selected group cipher suite (WPA_CIPHER_*)
*
* This is usually ignored if @wpa_ie is used.
*/
- enum wpa_cipher group_suite;
+ unsigned int group_suite;
/**
- * key_mgmt_suite - Selected key management suite
+ * key_mgmt_suite - Selected key management suite (WPA_KEY_MGMT_*)
*
* This is usually ignored if @wpa_ie is used.
*/
- enum wpa_key_mgmt key_mgmt_suite;
+ unsigned int key_mgmt_suite;
/**
* auth_alg - Allowed authentication algorithms
@@ -833,6 +848,12 @@
#define WPA_DRIVER_CAPA_ENC_CCMP 0x00000008
#define WPA_DRIVER_CAPA_ENC_WEP128 0x00000010
#define WPA_DRIVER_CAPA_ENC_GCMP 0x00000020
+#define WPA_DRIVER_CAPA_ENC_GCMP_256 0x00000040
+#define WPA_DRIVER_CAPA_ENC_CCMP_256 0x00000080
+#define WPA_DRIVER_CAPA_ENC_BIP 0x00000100
+#define WPA_DRIVER_CAPA_ENC_BIP_GMAC_128 0x00000200
+#define WPA_DRIVER_CAPA_ENC_BIP_GMAC_256 0x00000400
+#define WPA_DRIVER_CAPA_ENC_BIP_CMAC_256 0x00000800
unsigned int enc;
#define WPA_DRIVER_AUTH_OPEN 0x00000001
@@ -856,8 +877,7 @@
#define WPA_DRIVER_FLAGS_AP 0x00000040
/* Driver needs static WEP key setup after association has been completed */
#define WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE 0x00000080
-/* Driver takes care of P2P management operations */
-#define WPA_DRIVER_FLAGS_P2P_MGMT 0x00000100
+/* unused: 0x00000100 */
/* Driver supports concurrent P2P operations */
#define WPA_DRIVER_FLAGS_P2P_CONCURRENT 0x00000200
/*
@@ -910,6 +930,10 @@
#define WPA_DRIVER_FLAGS_RADAR 0x10000000
/* Driver supports a dedicated interface for P2P Device */
#define WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE 0x20000000
+/* Driver supports QoS Mapping */
+#define WPA_DRIVER_FLAGS_QOS_MAPPING 0x40000000
+/* Driver supports CSA in AP mode */
+#define WPA_DRIVER_FLAGS_AP_CSA 0x80000000
unsigned int flags;
int max_scan_ssids;
@@ -1099,17 +1123,6 @@
#define WPA_STA_MFP BIT(3)
#define WPA_STA_TDLS_PEER BIT(4)
-/**
- * struct p2p_params - P2P parameters for driver-based P2P management
- */
-struct p2p_params {
- const char *dev_name;
- u8 pri_dev_type[8];
-#define DRV_MAX_SEC_DEV_TYPES 5
- u8 sec_dev_type[DRV_MAX_SEC_DEV_TYPES][8];
- size_t num_sec_dev_types;
-};
-
enum tdls_oper {
TDLS_DISCOVERY_REQ,
TDLS_SETUP,
@@ -1265,7 +1278,9 @@
* @priv: private driver interface data
* @alg: encryption algorithm (%WPA_ALG_NONE, %WPA_ALG_WEP,
* %WPA_ALG_TKIP, %WPA_ALG_CCMP, %WPA_ALG_IGTK, %WPA_ALG_PMK,
- * %WPA_ALG_GCMP);
+ * %WPA_ALG_GCMP, %WPA_ALG_GCMP_256, %WPA_ALG_CCMP_256,
+ * %WPA_ALG_BIP_GMAC_128, %WPA_ALG_BIP_GMAC_256,
+ * %WPA_ALG_BIP_CMAC_256);
* %WPA_ALG_NONE clears the key.
* @addr: Address of the peer STA (BSSID of the current AP when setting
* pairwise key in station mode), ff:ff:ff:ff:ff:ff for
@@ -2206,7 +2221,7 @@
*
* This command is used to request the driver to remain awake on the
* specified channel for the specified duration and report received
- * Action frames with EVENT_RX_ACTION events. Optionally, received
+ * Action frames with EVENT_RX_MGMT events. Optionally, received
* Probe Request frames may also be requested to be reported by calling
* probe_req_report(). These will be reported with EVENT_RX_PROBE_REQ.
*
@@ -2388,222 +2403,6 @@
const char * (*get_radio_name)(void *priv);
/**
- * p2p_find - Start P2P Device Discovery
- * @priv: Private driver interface data
- * @timeout: Timeout for find operation in seconds or 0 for no timeout
- * @type: Device Discovery type (enum p2p_discovery_type)
- * Returns: 0 on success, -1 on failure
- *
- * This function is only used if the driver implements P2P management,
- * i.e., if it sets WPA_DRIVER_FLAGS_P2P_MGMT in
- * struct wpa_driver_capa.
- */
- int (*p2p_find)(void *priv, unsigned int timeout, int type);
-
- /**
- * p2p_stop_find - Stop P2P Device Discovery
- * @priv: Private driver interface data
- * Returns: 0 on success, -1 on failure
- *
- * This function is only used if the driver implements P2P management,
- * i.e., if it sets WPA_DRIVER_FLAGS_P2P_MGMT in
- * struct wpa_driver_capa.
- */
- int (*p2p_stop_find)(void *priv);
-
- /**
- * p2p_listen - Start P2P Listen state for specified duration
- * @priv: Private driver interface data
- * @timeout: Listen state duration in milliseconds
- * Returns: 0 on success, -1 on failure
- *
- * This function can be used to request the P2P module to keep the
- * device discoverable on the listen channel for an extended set of
- * time. At least in its current form, this is mainly used for testing
- * purposes and may not be of much use for normal P2P operations.
- *
- * This function is only used if the driver implements P2P management,
- * i.e., if it sets WPA_DRIVER_FLAGS_P2P_MGMT in
- * struct wpa_driver_capa.
- */
- int (*p2p_listen)(void *priv, unsigned int timeout);
-
- /**
- * p2p_connect - Start P2P group formation (GO negotiation)
- * @priv: Private driver interface data
- * @peer_addr: MAC address of the peer P2P client
- * @wps_method: enum p2p_wps_method value indicating config method
- * @go_intent: Local GO intent value (1..15)
- * @own_interface_addr: Intended interface address to use with the
- * group
- * @force_freq: The only allowed channel frequency in MHz or 0
- * @persistent_group: Whether to create persistent group
- * Returns: 0 on success, -1 on failure
- *
- * This function is only used if the driver implements P2P management,
- * i.e., if it sets WPA_DRIVER_FLAGS_P2P_MGMT in
- * struct wpa_driver_capa.
- */
- int (*p2p_connect)(void *priv, const u8 *peer_addr, int wps_method,
- int go_intent, const u8 *own_interface_addr,
- unsigned int force_freq, int persistent_group);
-
- /**
- * wps_success_cb - Report successfully completed WPS provisioning
- * @priv: Private driver interface data
- * @peer_addr: Peer address
- * Returns: 0 on success, -1 on failure
- *
- * This function is used to report successfully completed WPS
- * provisioning during group formation in both GO/Registrar and
- * client/Enrollee roles.
- *
- * This function is only used if the driver implements P2P management,
- * i.e., if it sets WPA_DRIVER_FLAGS_P2P_MGMT in
- * struct wpa_driver_capa.
- */
- int (*wps_success_cb)(void *priv, const u8 *peer_addr);
-
- /**
- * p2p_group_formation_failed - Report failed WPS provisioning
- * @priv: Private driver interface data
- * Returns: 0 on success, -1 on failure
- *
- * This function is used to report failed group formation. This can
- * happen either due to failed WPS provisioning or due to 15 second
- * timeout during the provisioning phase.
- *
- * This function is only used if the driver implements P2P management,
- * i.e., if it sets WPA_DRIVER_FLAGS_P2P_MGMT in
- * struct wpa_driver_capa.
- */
- int (*p2p_group_formation_failed)(void *priv);
-
- /**
- * p2p_set_params - Set P2P parameters
- * @priv: Private driver interface data
- * @params: P2P parameters
- * Returns: 0 on success, -1 on failure
- *
- * This function is only used if the driver implements P2P management,
- * i.e., if it sets WPA_DRIVER_FLAGS_P2P_MGMT in
- * struct wpa_driver_capa.
- */
- int (*p2p_set_params)(void *priv, const struct p2p_params *params);
-
- /**
- * p2p_prov_disc_req - Send Provision Discovery Request
- * @priv: Private driver interface data
- * @peer_addr: MAC address of the peer P2P client
- * @config_methods: WPS Config Methods value (only one bit set)
- * Returns: 0 on success, -1 on failure
- *
- * This function can be used to request a discovered P2P peer to
- * display a PIN (config_methods = WPS_CONFIG_DISPLAY) or be prepared
- * to enter a PIN from us (config_methods = WPS_CONFIG_KEYPAD). The
- * Provision Discovery Request frame is transmitted once immediately
- * and if no response is received, the frame will be sent again
- * whenever the target device is discovered during device dsicovery
- * (start with a p2p_find() call). Response from the peer is indicated
- * with the EVENT_P2P_PROV_DISC_RESPONSE event.
- *
- * This function is only used if the driver implements P2P management,
- * i.e., if it sets WPA_DRIVER_FLAGS_P2P_MGMT in
- * struct wpa_driver_capa.
- */
- int (*p2p_prov_disc_req)(void *priv, const u8 *peer_addr,
- u16 config_methods, int join);
-
- /**
- * p2p_sd_request - Schedule a service discovery query
- * @priv: Private driver interface data
- * @dst: Destination peer or %NULL to apply for all peers
- * @tlvs: P2P Service Query TLV(s)
- * Returns: Reference to the query or 0 on failure
- *
- * Response to the query is indicated with the
- * EVENT_P2P_SD_RESPONSE driver event.
- *
- * This function is only used if the driver implements P2P management,
- * i.e., if it sets WPA_DRIVER_FLAGS_P2P_MGMT in
- * struct wpa_driver_capa.
- */
- u64 (*p2p_sd_request)(void *priv, const u8 *dst,
- const struct wpabuf *tlvs);
-
- /**
- * p2p_sd_cancel_request - Cancel a pending service discovery query
- * @priv: Private driver interface data
- * @req: Query reference from p2p_sd_request()
- * Returns: 0 on success, -1 on failure
- *
- * This function is only used if the driver implements P2P management,
- * i.e., if it sets WPA_DRIVER_FLAGS_P2P_MGMT in
- * struct wpa_driver_capa.
- */
- int (*p2p_sd_cancel_request)(void *priv, u64 req);
-
- /**
- * p2p_sd_response - Send response to a service discovery query
- * @priv: Private driver interface data
- * @freq: Frequency from EVENT_P2P_SD_REQUEST event
- * @dst: Destination address from EVENT_P2P_SD_REQUEST event
- * @dialog_token: Dialog token from EVENT_P2P_SD_REQUEST event
- * @resp_tlvs: P2P Service Response TLV(s)
- * Returns: 0 on success, -1 on failure
- *
- * This function is called as a response to the request indicated with
- * the EVENT_P2P_SD_REQUEST driver event.
- *
- * This function is only used if the driver implements P2P management,
- * i.e., if it sets WPA_DRIVER_FLAGS_P2P_MGMT in
- * struct wpa_driver_capa.
- */
- int (*p2p_sd_response)(void *priv, int freq, const u8 *dst,
- u8 dialog_token,
- const struct wpabuf *resp_tlvs);
-
- /**
- * p2p_service_update - Indicate a change in local services
- * @priv: Private driver interface data
- * Returns: 0 on success, -1 on failure
- *
- * This function needs to be called whenever there is a change in
- * availability of the local services. This will increment the
- * Service Update Indicator value which will be used in SD Request and
- * Response frames.
- *
- * This function is only used if the driver implements P2P management,
- * i.e., if it sets WPA_DRIVER_FLAGS_P2P_MGMT in
- * struct wpa_driver_capa.
- */
- int (*p2p_service_update)(void *priv);
-
- /**
- * p2p_reject - Reject peer device (explicitly block connections)
- * @priv: Private driver interface data
- * @addr: MAC address of the peer
- * Returns: 0 on success, -1 on failure
- */
- int (*p2p_reject)(void *priv, const u8 *addr);
-
- /**
- * p2p_invite - Invite a P2P Device into a group
- * @priv: Private driver interface data
- * @peer: Device Address of the peer P2P Device
- * @role: Local role in the group
- * @bssid: Group BSSID or %NULL if not known
- * @ssid: Group SSID
- * @ssid_len: Length of ssid in octets
- * @go_dev_addr: Forced GO Device Address or %NULL if none
- * @persistent_group: Whether this is to reinvoke a persistent group
- * Returns: 0 on success, -1 on failure
- */
- int (*p2p_invite)(void *priv, const u8 *peer, int role,
- const u8 *bssid, const u8 *ssid, size_t ssid_len,
- const u8 *go_dev_addr, int persistent_group);
-
- /**
* send_tdls_mgmt - for sending TDLS management packets
* @priv: private driver interface data
* @dst: Destination (peer) MAC address
@@ -3092,15 +2891,6 @@
EVENT_RX_MGMT,
/**
- * EVENT_RX_ACTION - Action frame received
- *
- * This event is used to indicate when an Action frame has been
- * received. Information about the received frame is included in
- * union wpa_event_data::rx_action.
- */
- EVENT_RX_ACTION,
-
- /**
* EVENT_REMAIN_ON_CHANNEL - Remain-on-channel duration started
*
* This event is used to indicate when the driver has started the
@@ -3247,38 +3037,6 @@
EVENT_STATION_LOW_ACK,
/**
- * EVENT_P2P_DEV_FOUND - Report a discovered P2P device
- *
- * This event is used only if the driver implements P2P management
- * internally. Event data is stored in
- * union wpa_event_data::p2p_dev_found.
- */
- EVENT_P2P_DEV_FOUND,
-
- /**
- * EVENT_P2P_GO_NEG_REQ_RX - Report reception of GO Negotiation Request
- *
- * This event is used only if the driver implements P2P management
- * internally. Event data is stored in
- * union wpa_event_data::p2p_go_neg_req_rx.
- */
- EVENT_P2P_GO_NEG_REQ_RX,
-
- /**
- * EVENT_P2P_GO_NEG_COMPLETED - Report completion of GO Negotiation
- *
- * This event is used only if the driver implements P2P management
- * internally. Event data is stored in
- * union wpa_event_data::p2p_go_neg_completed.
- */
- EVENT_P2P_GO_NEG_COMPLETED,
-
- EVENT_P2P_PROV_DISC_REQUEST,
- EVENT_P2P_PROV_DISC_RESPONSE,
- EVENT_P2P_SD_REQUEST,
- EVENT_P2P_SD_RESPONSE,
-
- /**
* EVENT_IBSS_PEER_LOST - IBSS peer not reachable anymore
*/
EVENT_IBSS_PEER_LOST,
@@ -3365,17 +3123,27 @@
*/
EVENT_DFS_NOP_FINISHED,
- /*
- * EVENT_SURVEY - Received survey data
- *
- * This event gets triggered when a driver query is issued for survey
- * data and the requested data becomes available. The returned data is
- * stored in struct survey_results. The results provide at most one
- * survey entry for each frequency and at minimum will provide one survey
- * entry for one frequency. The survey data can be os_malloc()'d and
- * then os_free()'d, so the event callback must only copy data.
- */
- EVENT_SURVEY
+ /**
+ * EVENT_SURVEY - Received survey data
+ *
+ * This event gets triggered when a driver query is issued for survey
+ * data and the requested data becomes available. The returned data is
+ * stored in struct survey_results. The results provide at most one
+ * survey entry for each frequency and at minimum will provide one
+ * survey entry for one frequency. The survey data can be os_malloc()'d
+ * and then os_free()'d, so the event callback must only copy data.
+ */
+ EVENT_SURVEY,
+
+ /**
+ * EVENT_SCAN_STARTED - Scan started
+ *
+ * This indicates that driver has started a scan operation either based
+ * on a request from wpa_supplicant/hostapd or from another application.
+ * EVENT_SCAN_RESULTS is used to indicate when the scan has been
+ * completed (either successfully or by getting cancelled).
+ */
+ EVENT_SCAN_STARTED
};
@@ -3743,48 +3511,17 @@
const u8 *frame;
size_t frame_len;
u32 datarate;
- int ssi_signal; /* dBm */
- } rx_mgmt;
-
- /**
- * struct rx_action - Data for EVENT_RX_ACTION events
- */
- struct rx_action {
- /**
- * da - Destination address of the received Action frame
- */
- const u8 *da;
-
- /**
- * sa - Source address of the received Action frame
- */
- const u8 *sa;
-
- /**
- * bssid - Address 3 of the received Action frame
- */
- const u8 *bssid;
-
- /**
- * category - Action frame category
- */
- u8 category;
-
- /**
- * data - Action frame body after category field
- */
- const u8 *data;
-
- /**
- * len - Length of data in octets
- */
- size_t len;
/**
* freq - Frequency (in MHz) on which the frame was received
*/
int freq;
- } rx_action;
+
+ /**
+ * ssi_signal - Signal strength in dBm (or 0 if not available)
+ */
+ int ssi_signal;
+ } rx_mgmt;
/**
* struct remain_on_channel - Data for EVENT_REMAIN_ON_CHANNEL events
@@ -3924,66 +3661,6 @@
} low_ack;
/**
- * struct p2p_dev_found - Data for EVENT_P2P_DEV_FOUND
- */
- struct p2p_dev_found {
- const u8 *addr;
- const u8 *dev_addr;
- const u8 *pri_dev_type;
- const char *dev_name;
- u16 config_methods;
- u8 dev_capab;
- u8 group_capab;
- } p2p_dev_found;
-
- /**
- * struct p2p_go_neg_req_rx - Data for EVENT_P2P_GO_NEG_REQ_RX
- */
- struct p2p_go_neg_req_rx {
- const u8 *src;
- u16 dev_passwd_id;
- } p2p_go_neg_req_rx;
-
- /**
- * struct p2p_go_neg_completed - Data for EVENT_P2P_GO_NEG_COMPLETED
- */
- struct p2p_go_neg_completed {
- struct p2p_go_neg_results *res;
- } p2p_go_neg_completed;
-
- struct p2p_prov_disc_req {
- const u8 *peer;
- u16 config_methods;
- const u8 *dev_addr;
- const u8 *pri_dev_type;
- const char *dev_name;
- u16 supp_config_methods;
- u8 dev_capab;
- u8 group_capab;
- } p2p_prov_disc_req;
-
- struct p2p_prov_disc_resp {
- const u8 *peer;
- u16 config_methods;
- } p2p_prov_disc_resp;
-
- struct p2p_sd_req {
- int freq;
- const u8 *sa;
- u8 dialog_token;
- u16 update_indic;
- const u8 *tlvs;
- size_t tlvs_len;
- } p2p_sd_req;
-
- struct p2p_sd_resp {
- const u8 *sa;
- u16 update_indic;
- const u8 *tlvs;
- size_t tlvs_len;
- } p2p_sd_resp;
-
- /**
* struct ibss_peer_lost - Data for EVENT_IBSS_PEER_LOST
*/
struct ibss_peer_lost {
@@ -4143,4 +3820,7 @@
/* Convert wpa_event_type to a string for logging */
const char * event_to_string(enum wpa_event_type event);
+/* NULL terminated array of linked in driver wrappers */
+extern struct wpa_driver_ops *wpa_drivers[];
+
#endif /* DRIVER_H */
diff --git a/src/drivers/driver_atheros.c b/src/drivers/driver_atheros.c
index 7d301f7..23a4e2b 100644
--- a/src/drivers/driver_atheros.c
+++ b/src/drivers/driver_atheros.c
@@ -806,16 +806,10 @@
drv_event_assoc(drv->hapd, mgmt->sa, iebuf, ielen, 1);
break;
case WLAN_FC_STYPE_ACTION:
- if (&mgmt->u.action.category > buf + len)
- break;
os_memset(&event, 0, sizeof(event));
- event.rx_action.da = mgmt->da;
- event.rx_action.sa = mgmt->sa;
- event.rx_action.bssid = mgmt->bssid;
- event.rx_action.category = mgmt->u.action.category;
- event.rx_action.data = &mgmt->u.action.category;
- event.rx_action.len = buf + len - event.rx_action.data;
- wpa_supplicant_event(drv->hapd, EVENT_RX_ACTION, &event);
+ event.rx_mgmt.frame = buf;
+ event.rx_mgmt.frame_len = len;
+ wpa_supplicant_event(drv->hapd, EVENT_RX_MGMT, &event);
break;
case WLAN_FC_STYPE_AUTH:
if (len - IEEE80211_HDRLEN < sizeof(mgmt->u.auth))
@@ -954,16 +948,10 @@
switch (stype) {
case WLAN_FC_STYPE_ACTION:
- if (&mgmt->u.action.category > buf + len)
- break;
os_memset(&event, 0, sizeof(event));
- event.rx_action.da = mgmt->da;
- event.rx_action.sa = mgmt->sa;
- event.rx_action.bssid = mgmt->bssid;
- event.rx_action.category = mgmt->u.action.category;
- event.rx_action.data = &mgmt->u.action.category;
- event.rx_action.len = buf + len - event.rx_action.data;
- wpa_supplicant_event(drv->hapd, EVENT_RX_ACTION, &event);
+ event.rx_mgmt.frame = buf;
+ event.rx_mgmt.frame_len = len;
+ wpa_supplicant_event(drv->hapd, EVENT_RX_MGMT, &event);
break;
default:
break;
diff --git a/src/drivers/driver_bsd.c b/src/drivers/driver_bsd.c
index fb6402d..7f5e231 100644
--- a/src/drivers/driver_bsd.c
+++ b/src/drivers/driver_bsd.c
@@ -1110,9 +1110,9 @@
if (wpa_driver_bsd_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0)
return -1;
- privacy = !(params->pairwise_suite == CIPHER_NONE &&
- params->group_suite == CIPHER_NONE &&
- params->key_mgmt_suite == KEY_MGMT_NONE &&
+ privacy = !(params->pairwise_suite == WPA_CIPHER_NONE &&
+ params->group_suite == WPA_CIPHER_NONE &&
+ params->key_mgmt_suite == WPA_KEY_MGMT_NONE &&
params->wpa_ie_len == 0);
wpa_printf(MSG_DEBUG, "%s: set PRIVACY %u", __func__, privacy);
diff --git a/src/drivers/driver_common.c b/src/drivers/driver_common.c
index 8d1d22e..64bdddb 100644
--- a/src/drivers/driver_common.c
+++ b/src/drivers/driver_common.c
@@ -49,7 +49,6 @@
E2S(TX_STATUS);
E2S(RX_FROM_UNKNOWN);
E2S(RX_MGMT);
- E2S(RX_ACTION);
E2S(REMAIN_ON_CHANNEL);
E2S(CANCEL_REMAIN_ON_CHANNEL);
E2S(MLME_RX);
@@ -65,13 +64,6 @@
E2S(UNPROT_DEAUTH);
E2S(UNPROT_DISASSOC);
E2S(STATION_LOW_ACK);
- E2S(P2P_DEV_FOUND);
- E2S(P2P_GO_NEG_REQ_RX);
- E2S(P2P_GO_NEG_COMPLETED);
- E2S(P2P_PROV_DISC_REQUEST);
- E2S(P2P_PROV_DISC_RESPONSE);
- E2S(P2P_SD_REQUEST);
- E2S(P2P_SD_RESPONSE);
E2S(IBSS_PEER_LOST);
E2S(DRIVER_GTK_REKEY);
E2S(SCHED_SCAN_STOPPED);
@@ -85,6 +77,7 @@
E2S(DFS_CAC_ABORTED);
E2S(DFS_NOP_FINISHED);
E2S(SURVEY);
+ E2S(SCAN_STARTED);
}
return "UNKNOWN";
diff --git a/src/drivers/driver_madwifi.c b/src/drivers/driver_madwifi.c
index 0930834..1635c1f 100644
--- a/src/drivers/driver_madwifi.c
+++ b/src/drivers/driver_madwifi.c
@@ -1,5 +1,5 @@
/*
- * WPA Supplicant - driver interaction with MADWIFI 802.11 driver
+ * hostapd - driver interaction with MADWIFI 802.11 driver
* Copyright (c) 2004, Sam Leffler <sam@errno.com>
* Copyright (c) 2004, Video54 Technologies
* Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
@@ -7,10 +7,9 @@
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*
- * While this driver wrapper supports both AP (hostapd) and station
- * (wpa_supplicant) operations, the station side is deprecated and
- * driver_wext.c should be used instead. This driver wrapper should only be
- * used with hostapd for AP mode functionality.
+ * This driver wrapper is only for hostapd AP mode functionality. Station
+ * (wpa_supplicant) operations with madwifi are supported by the driver_wext.c
+ * wrapper.
*/
#include "includes.h"
diff --git a/src/drivers/driver_ndis.c b/src/drivers/driver_ndis.c
index 4656c1b..4953af6 100644
--- a/src/drivers/driver_ndis.c
+++ b/src/drivers/driver_ndis.c
@@ -1074,8 +1074,8 @@
/* Try to continue anyway */
}
- if (params->key_mgmt_suite == KEY_MGMT_NONE ||
- params->key_mgmt_suite == KEY_MGMT_802_1X_NO_WPA) {
+ if (params->key_mgmt_suite == WPA_KEY_MGMT_NONE ||
+ params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
/* Re-set WEP keys if static WEP configuration is used. */
int i;
for (i = 0; i < 4; i++) {
@@ -1102,12 +1102,12 @@
priv_mode = Ndis802_11PrivFilterAcceptAll;
} else if (params->wpa_ie[0] == WLAN_EID_RSN) {
priv_mode = Ndis802_11PrivFilter8021xWEP;
- if (params->key_mgmt_suite == KEY_MGMT_PSK)
+ if (params->key_mgmt_suite == WPA_KEY_MGMT_PSK)
auth_mode = Ndis802_11AuthModeWPA2PSK;
else
auth_mode = Ndis802_11AuthModeWPA2;
#ifdef CONFIG_WPS
- } else if (params->key_mgmt_suite == KEY_MGMT_WPS) {
+ } else if (params->key_mgmt_suite == WPA_KEY_MGMT_WPS) {
auth_mode = Ndis802_11AuthModeOpen;
priv_mode = Ndis802_11PrivFilterAcceptAll;
if (params->wps == WPS_MODE_PRIVACY) {
@@ -1129,35 +1129,35 @@
#endif /* CONFIG_WPS */
} else {
priv_mode = Ndis802_11PrivFilter8021xWEP;
- if (params->key_mgmt_suite == KEY_MGMT_WPA_NONE)
+ if (params->key_mgmt_suite == WPA_KEY_MGMT_WPA_NONE)
auth_mode = Ndis802_11AuthModeWPANone;
- else if (params->key_mgmt_suite == KEY_MGMT_PSK)
+ else if (params->key_mgmt_suite == WPA_KEY_MGMT_PSK)
auth_mode = Ndis802_11AuthModeWPAPSK;
else
auth_mode = Ndis802_11AuthModeWPA;
}
switch (params->pairwise_suite) {
- case CIPHER_CCMP:
+ case WPA_CIPHER_CCMP:
encr = Ndis802_11Encryption3Enabled;
break;
- case CIPHER_TKIP:
+ case WPA_CIPHER_TKIP:
encr = Ndis802_11Encryption2Enabled;
break;
- case CIPHER_WEP40:
- case CIPHER_WEP104:
+ case WPA_CIPHER_WEP40:
+ case WPA_CIPHER_WEP104:
encr = Ndis802_11Encryption1Enabled;
break;
- case CIPHER_NONE:
+ case WPA_CIPHER_NONE:
#ifdef CONFIG_WPS
if (params->wps == WPS_MODE_PRIVACY) {
encr = Ndis802_11Encryption1Enabled;
break;
}
#endif /* CONFIG_WPS */
- if (params->group_suite == CIPHER_CCMP)
+ if (params->group_suite == WPA_CIPHER_CCMP)
encr = Ndis802_11Encryption3Enabled;
- else if (params->group_suite == CIPHER_TKIP)
+ else if (params->group_suite == WPA_CIPHER_TKIP)
encr = Ndis802_11Encryption2Enabled;
else
encr = Ndis802_11EncryptionDisabled;
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 42dddf0..fce6efd 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -1,6 +1,6 @@
/*
* Driver interaction with Linux nl80211/cfg80211
- * Copyright (c) 2002-2012, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi>
* Copyright (c) 2003-2004, Instant802 Networks, Inc.
* Copyright (c) 2005-2006, Devicescape Software, Inc.
* Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
@@ -300,7 +300,6 @@
unsigned int hostapd:1;
unsigned int start_mode_ap:1;
unsigned int start_iface_up:1;
- unsigned int channel_switch_supported:1;
u64 remain_on_chan_cookie;
u64 send_action_cookie;
@@ -497,6 +496,11 @@
C2S(NL80211_CMD_FT_EVENT)
C2S(NL80211_CMD_CRIT_PROTOCOL_START)
C2S(NL80211_CMD_CRIT_PROTOCOL_STOP)
+ C2S(NL80211_CMD_GET_COALESCE)
+ C2S(NL80211_CMD_SET_COALESCE)
+ C2S(NL80211_CMD_CHANNEL_SWITCH)
+ C2S(NL80211_CMD_VENDOR)
+ C2S(NL80211_CMD_SET_QOS_MAP)
default:
return "NL80211_CMD_UNKNOWN";
}
@@ -1045,49 +1049,55 @@
}
-static void wpa_driver_nl80211_event_link(struct wpa_driver_nl80211_data *drv,
- char *buf, size_t len, int del)
+static void wpa_driver_nl80211_event_newlink(
+ struct wpa_driver_nl80211_data *drv, char *ifname)
{
union wpa_event_data event;
- os_memset(&event, 0, sizeof(event));
- if (len > sizeof(event.interface_status.ifname))
- len = sizeof(event.interface_status.ifname) - 1;
- os_memcpy(event.interface_status.ifname, buf, len);
- event.interface_status.ievent = del ? EVENT_INTERFACE_REMOVED :
- EVENT_INTERFACE_ADDED;
-
- wpa_printf(MSG_DEBUG, "RTM_%sLINK, IFLA_IFNAME: Interface '%s' %s",
- del ? "DEL" : "NEW",
- event.interface_status.ifname,
- del ? "removed" : "added");
-
- if (os_strcmp(drv->first_bss->ifname, event.interface_status.ifname) ==
- 0) {
- if (del) {
- if (drv->if_removed) {
- wpa_printf(MSG_DEBUG, "nl80211: if_removed "
- "already set - ignore event");
- return;
- }
- drv->if_removed = 1;
- } else {
- if (if_nametoindex(drv->first_bss->ifname) == 0) {
- wpa_printf(MSG_DEBUG, "nl80211: Interface %s "
- "does not exist - ignore "
- "RTM_NEWLINK",
- drv->first_bss->ifname);
- return;
- }
- if (!drv->if_removed) {
- wpa_printf(MSG_DEBUG, "nl80211: if_removed "
- "already cleared - ignore event");
- return;
- }
- drv->if_removed = 0;
+ if (os_strcmp(drv->first_bss->ifname, ifname) == 0) {
+ if (if_nametoindex(drv->first_bss->ifname) == 0) {
+ wpa_printf(MSG_DEBUG, "nl80211: Interface %s does not exist - ignore RTM_NEWLINK",
+ drv->first_bss->ifname);
+ return;
}
+ if (!drv->if_removed)
+ return;
+ wpa_printf(MSG_DEBUG, "nl80211: Mark if_removed=0 for %s based on RTM_NEWLINK event",
+ drv->first_bss->ifname);
+ drv->if_removed = 0;
}
+ os_memset(&event, 0, sizeof(event));
+ os_strlcpy(event.interface_status.ifname, ifname,
+ sizeof(event.interface_status.ifname));
+ event.interface_status.ievent = EVENT_INTERFACE_ADDED;
+ wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
+}
+
+
+static void wpa_driver_nl80211_event_dellink(
+ struct wpa_driver_nl80211_data *drv, char *ifname)
+{
+ union wpa_event_data event;
+
+ if (os_strcmp(drv->first_bss->ifname, ifname) == 0) {
+ if (drv->if_removed) {
+ wpa_printf(MSG_DEBUG, "nl80211: if_removed already set - ignore RTM_DELLINK event for %s",
+ ifname);
+ return;
+ }
+ wpa_printf(MSG_DEBUG, "RTM_DELLINK: Interface '%s' removed - mark if_removed=1",
+ ifname);
+ drv->if_removed = 1;
+ } else {
+ wpa_printf(MSG_DEBUG, "RTM_DELLINK: Interface '%s' removed",
+ ifname);
+ }
+
+ os_memset(&event, 0, sizeof(event));
+ os_strlcpy(event.interface_status.ifname, ifname,
+ sizeof(event.interface_status.ifname));
+ event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
}
@@ -1154,21 +1164,57 @@
{
struct nl80211_global *global = ctx;
struct wpa_driver_nl80211_data *drv;
- int attrlen, rta_len;
+ int attrlen;
struct rtattr *attr;
u32 brid = 0;
char namebuf[IFNAMSIZ];
+ char ifname[IFNAMSIZ + 1];
+ char extra[100], *pos, *end;
drv = nl80211_find_drv(global, ifi->ifi_index, buf, len);
if (!drv) {
- wpa_printf(MSG_DEBUG, "nl80211: Ignore event for foreign "
- "ifindex %d", ifi->ifi_index);
+ wpa_printf(MSG_DEBUG, "nl80211: Ignore RTM_NEWLINK event for foreign ifindex %d",
+ ifi->ifi_index);
return;
}
- wpa_printf(MSG_DEBUG, "RTM_NEWLINK: operstate=%d ifi_flags=0x%x "
- "(%s%s%s%s)",
- drv->operstate, ifi->ifi_flags,
+ extra[0] = '\0';
+ pos = extra;
+ end = pos + sizeof(extra);
+ ifname[0] = '\0';
+
+ attrlen = len;
+ attr = (struct rtattr *) buf;
+ while (RTA_OK(attr, attrlen)) {
+ switch (attr->rta_type) {
+ case IFLA_IFNAME:
+ if (RTA_PAYLOAD(attr) >= IFNAMSIZ)
+ break;
+ os_memcpy(ifname, RTA_DATA(attr), RTA_PAYLOAD(attr));
+ ifname[RTA_PAYLOAD(attr)] = '\0';
+ break;
+ case IFLA_MASTER:
+ brid = nla_get_u32((struct nlattr *) attr);
+ pos += os_snprintf(pos, end - pos, " master=%u", brid);
+ break;
+ case IFLA_WIRELESS:
+ pos += os_snprintf(pos, end - pos, " wext");
+ break;
+ case IFLA_OPERSTATE:
+ pos += os_snprintf(pos, end - pos, " operstate=%u",
+ nla_get_u32((struct nlattr *) attr));
+ break;
+ case IFLA_LINKMODE:
+ pos += os_snprintf(pos, end - pos, " linkmode=%u",
+ nla_get_u32((struct nlattr *) attr));
+ break;
+ }
+ attr = RTA_NEXT(attr, attrlen);
+ }
+ extra[sizeof(extra) - 1] = '\0';
+
+ wpa_printf(MSG_DEBUG, "RTM_NEWLINK: ifi_index=%d ifname=%s%s ifi_flags=0x%x (%s%s%s%s)",
+ ifi->ifi_index, ifname, extra, ifi->ifi_flags,
(ifi->ifi_flags & IFF_UP) ? "[UP]" : "",
(ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "",
(ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
@@ -1225,24 +1271,15 @@
*/
if (drv->operstate == 1 &&
(ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP &&
- !(ifi->ifi_flags & IFF_RUNNING))
+ !(ifi->ifi_flags & IFF_RUNNING)) {
+ wpa_printf(MSG_DEBUG, "nl80211: Set IF_OPER_UP again based on ifi_flags and expected operstate");
netlink_send_oper_ifla(drv->global->netlink, drv->ifindex,
-1, IF_OPER_UP);
-
- attrlen = len;
- attr = (struct rtattr *) buf;
- rta_len = RTA_ALIGN(sizeof(struct rtattr));
- while (RTA_OK(attr, attrlen)) {
- if (attr->rta_type == IFLA_IFNAME) {
- wpa_driver_nl80211_event_link(
- drv,
- ((char *) attr) + rta_len,
- attr->rta_len - rta_len, 0);
- } else if (attr->rta_type == IFLA_MASTER)
- brid = nla_get_u32((struct nlattr *) attr);
- attr = RTA_NEXT(attr, attrlen);
}
+ if (ifname[0])
+ wpa_driver_nl80211_event_newlink(drv, ifname);
+
if (ifi->ifi_family == AF_BRIDGE && brid) {
/* device has been added to bridge */
if_indextoname(brid, namebuf);
@@ -1259,32 +1296,40 @@
{
struct nl80211_global *global = ctx;
struct wpa_driver_nl80211_data *drv;
- int attrlen, rta_len;
+ int attrlen;
struct rtattr *attr;
u32 brid = 0;
+ char ifname[IFNAMSIZ + 1];
drv = nl80211_find_drv(global, ifi->ifi_index, buf, len);
if (!drv) {
- wpa_printf(MSG_DEBUG, "nl80211: Ignore dellink event for "
- "foreign ifindex %d", ifi->ifi_index);
+ wpa_printf(MSG_DEBUG, "nl80211: Ignore RTM_DELLINK event for foreign ifindex %d",
+ ifi->ifi_index);
return;
}
+ ifname[0] = '\0';
+
attrlen = len;
attr = (struct rtattr *) buf;
-
- rta_len = RTA_ALIGN(sizeof(struct rtattr));
while (RTA_OK(attr, attrlen)) {
- if (attr->rta_type == IFLA_IFNAME) {
- wpa_driver_nl80211_event_link(
- drv,
- ((char *) attr) + rta_len,
- attr->rta_len - rta_len, 1);
- } else if (attr->rta_type == IFLA_MASTER)
+ switch (attr->rta_type) {
+ case IFLA_IFNAME:
+ if (RTA_PAYLOAD(attr) >= IFNAMSIZ)
+ break;
+ os_memcpy(ifname, RTA_DATA(attr), RTA_PAYLOAD(attr));
+ ifname[RTA_PAYLOAD(attr)] = '\0';
+ break;
+ case IFLA_MASTER:
brid = nla_get_u32((struct nlattr *) attr);
+ break;
+ }
attr = RTA_NEXT(attr, attrlen);
}
+ if (ifname[0])
+ wpa_driver_nl80211_event_dellink(drv, ifname);
+
if (ifi->ifi_family == AF_BRIDGE && brid) {
/* device has been removed from bridge */
char namebuf[IFNAMSIZ];
@@ -1602,7 +1647,7 @@
wpa_printf(MSG_MSGDUMP, "nl80211: Frame event");
mgmt = (const struct ieee80211_mgmt *) frame;
if (len < 24) {
- wpa_printf(MSG_DEBUG, "nl80211: Too short action frame");
+ wpa_printf(MSG_DEBUG, "nl80211: Too short management frame");
return;
}
@@ -1614,26 +1659,16 @@
os_memset(&event, 0, sizeof(event));
if (freq) {
- event.rx_action.freq = nla_get_u32(freq);
- rx_freq = drv->last_mgmt_freq = event.rx_action.freq;
+ event.rx_mgmt.freq = nla_get_u32(freq);
+ rx_freq = drv->last_mgmt_freq = event.rx_mgmt.freq;
}
wpa_printf(MSG_DEBUG,
"nl80211: RX frame freq=%d ssi_signal=%d stype=%u len=%u",
rx_freq, ssi_signal, stype, (unsigned int) len);
- if (stype == WLAN_FC_STYPE_ACTION) {
- event.rx_action.da = mgmt->da;
- event.rx_action.sa = mgmt->sa;
- event.rx_action.bssid = mgmt->bssid;
- event.rx_action.category = mgmt->u.action.category;
- event.rx_action.data = &mgmt->u.action.category + 1;
- event.rx_action.len = frame + len - event.rx_action.data;
- wpa_supplicant_event(drv->ctx, EVENT_RX_ACTION, &event);
- } else {
- event.rx_mgmt.frame = frame;
- event.rx_mgmt.frame_len = len;
- event.rx_mgmt.ssi_signal = ssi_signal;
- wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
- }
+ event.rx_mgmt.frame = frame;
+ event.rx_mgmt.frame_len = len;
+ event.rx_mgmt.ssi_signal = ssi_signal;
+ wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
}
@@ -2037,21 +2072,36 @@
&info->ssids[info->num_ssids];
s->ssid = nla_data(nl);
s->ssid_len = nla_len(nl);
+ wpa_printf(MSG_DEBUG, "nl80211: Scan probed for SSID '%s'",
+ wpa_ssid_txt(s->ssid, s->ssid_len));
info->num_ssids++;
if (info->num_ssids == WPAS_MAX_SCAN_SSIDS)
break;
}
}
if (tb[NL80211_ATTR_SCAN_FREQUENCIES]) {
+ char msg[200], *pos, *end;
+ int res;
+
+ pos = msg;
+ end = pos + sizeof(msg);
+ *pos = '\0';
+
nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_FREQUENCIES], rem)
{
freqs[num_freqs] = nla_get_u32(nl);
+ res = os_snprintf(pos, end - pos, " %d",
+ freqs[num_freqs]);
+ if (res > 0 && end - pos > res)
+ pos += res;
num_freqs++;
if (num_freqs == MAX_REPORT_FREQS - 1)
break;
}
info->freqs = freqs;
info->num_freqs = num_freqs;
+ wpa_printf(MSG_DEBUG, "nl80211: Scan included frequencies:%s",
+ msg);
}
wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, &event);
}
@@ -2666,6 +2716,48 @@
}
+static void nl80211_vendor_event(struct wpa_driver_nl80211_data *drv,
+ struct nlattr **tb)
+{
+ u32 vendor_id, subcmd, wiphy = 0;
+ int wiphy_idx;
+ u8 *data = NULL;
+ size_t len = 0;
+
+ if (!tb[NL80211_ATTR_VENDOR_ID] ||
+ !tb[NL80211_ATTR_VENDOR_SUBCMD])
+ return;
+
+ vendor_id = nla_get_u32(tb[NL80211_ATTR_VENDOR_ID]);
+ subcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
+
+ if (tb[NL80211_ATTR_WIPHY])
+ wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
+
+ wpa_printf(MSG_DEBUG, "nl80211: Vendor event: wiphy=%u vendor_id=0x%x subcmd=%u",
+ wiphy, vendor_id, subcmd);
+
+ if (tb[NL80211_ATTR_VENDOR_DATA]) {
+ data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
+ len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
+ wpa_hexdump(MSG_MSGDUMP, "nl80211: Vendor data", data, len);
+ }
+
+ wiphy_idx = nl80211_get_wiphy_index(drv->first_bss);
+ if (wiphy_idx >= 0 && wiphy_idx != (int) wiphy) {
+ wpa_printf(MSG_DEBUG, "nl80211: Ignore vendor event for foreign wiphy %u (own: %d)",
+ wiphy, wiphy_idx);
+ return;
+ }
+
+ switch (vendor_id) {
+ default:
+ wpa_printf(MSG_DEBUG, "nl80211: Ignore unsupported vendor event");
+ break;
+ }
+}
+
+
static void do_process_drv_event(struct i802_bss *bss, int cmd,
struct nlattr **tb)
{
@@ -2687,6 +2779,7 @@
case NL80211_CMD_TRIGGER_SCAN:
wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan trigger");
drv->scan_state = SCAN_STARTED;
+ wpa_supplicant_event(drv->ctx, EVENT_SCAN_STARTED, NULL);
break;
case NL80211_CMD_START_SCHED_SCAN:
wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan started");
@@ -2838,6 +2931,9 @@
case NL80211_CMD_STOP_AP:
nl80211_stop_ap(drv, tb);
break;
+ case NL80211_CMD_VENDOR:
+ nl80211_vendor_event(drv, tb);
+ break;
default:
wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event "
"(cmd=%d)", cmd);
@@ -3105,6 +3201,7 @@
unsigned int p2p_client_supported:1;
unsigned int p2p_concurrent:1;
unsigned int channel_switch_supported:1;
+ unsigned int set_qos_map_supported:1;
};
@@ -3265,6 +3362,65 @@
case NL80211_CMD_CHANNEL_SWITCH:
info->channel_switch_supported = 1;
break;
+ case NL80211_CMD_SET_QOS_MAP:
+ info->set_qos_map_supported = 1;
+ break;
+ }
+ }
+}
+
+
+static void wiphy_info_cipher_suites(struct wiphy_info_data *info,
+ struct nlattr *tb)
+{
+ int i, num;
+ u32 *ciphers;
+
+ if (tb == NULL)
+ return;
+
+ num = nla_len(tb) / sizeof(u32);
+ ciphers = nla_data(tb);
+ for (i = 0; i < num; i++) {
+ u32 c = ciphers[i];
+
+ wpa_printf(MSG_DEBUG, "nl80211: Supported cipher %02x-%02x-%02x:%d",
+ c >> 24, (c >> 16) & 0xff,
+ (c >> 8) & 0xff, c & 0xff);
+ switch (c) {
+ case WLAN_CIPHER_SUITE_CCMP_256:
+ info->capa->enc |= WPA_DRIVER_CAPA_ENC_CCMP_256;
+ break;
+ case WLAN_CIPHER_SUITE_GCMP_256:
+ info->capa->enc |= WPA_DRIVER_CAPA_ENC_GCMP_256;
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ info->capa->enc |= WPA_DRIVER_CAPA_ENC_CCMP;
+ break;
+ case WLAN_CIPHER_SUITE_GCMP:
+ info->capa->enc |= WPA_DRIVER_CAPA_ENC_GCMP;
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+ info->capa->enc |= WPA_DRIVER_CAPA_ENC_TKIP;
+ break;
+ case WLAN_CIPHER_SUITE_WEP104:
+ info->capa->enc |= WPA_DRIVER_CAPA_ENC_WEP104;
+ break;
+ case WLAN_CIPHER_SUITE_WEP40:
+ info->capa->enc |= WPA_DRIVER_CAPA_ENC_WEP40;
+ break;
+ case WLAN_CIPHER_SUITE_AES_CMAC:
+ info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP;
+ break;
+ case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+ info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_GMAC_128;
+ break;
+ case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+ info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_GMAC_256;
+ break;
+ case WLAN_CIPHER_SUITE_BIP_CMAC_256:
+ info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_CMAC_256;
+ break;
}
}
}
@@ -3369,6 +3525,7 @@
wiphy_info_supported_iftypes(info, tb[NL80211_ATTR_SUPPORTED_IFTYPES]);
wiphy_info_iface_comb(info, tb[NL80211_ATTR_INTERFACE_COMBINATIONS]);
wiphy_info_supp_cmds(info, tb[NL80211_ATTR_SUPPORTED_COMMANDS]);
+ wiphy_info_cipher_suites(info, tb[NL80211_ATTR_CIPHER_SUITES]);
if (tb[NL80211_ATTR_OFFCHANNEL_TX_OK]) {
wpa_printf(MSG_DEBUG, "nl80211: Using driver-based "
@@ -3421,6 +3578,38 @@
}
}
+ if (tb[NL80211_ATTR_VENDOR_DATA]) {
+ struct nlattr *nl;
+ int rem;
+
+ nla_for_each_nested(nl, tb[NL80211_ATTR_VENDOR_DATA], rem) {
+ struct nl80211_vendor_cmd_info *vinfo;
+ if (nla_len(nl) != sizeof(vinfo)) {
+ wpa_printf(MSG_DEBUG, "nl80211: Unexpected vendor data info");
+ continue;
+ }
+ vinfo = nla_data(nl);
+ wpa_printf(MSG_DEBUG, "nl80211: Supported vendor command: vendor_id=0x%x subcmd=%u",
+ vinfo->vendor_id, vinfo->subcmd);
+ }
+ }
+
+ if (tb[NL80211_ATTR_VENDOR_EVENTS]) {
+ struct nlattr *nl;
+ int rem;
+
+ nla_for_each_nested(nl, tb[NL80211_ATTR_VENDOR_EVENTS], rem) {
+ struct nl80211_vendor_cmd_info *vinfo;
+ if (nla_len(nl) != sizeof(vinfo)) {
+ wpa_printf(MSG_DEBUG, "nl80211: Unexpected vendor data info");
+ continue;
+ }
+ vinfo = nla_data(nl);
+ wpa_printf(MSG_DEBUG, "nl80211: Supported vendor event: vendor_id=0x%x subcmd=%u",
+ vinfo->vendor_id, vinfo->subcmd);
+ }
+ }
+
return NL_SKIP;
}
@@ -3479,6 +3668,9 @@
if (!drv->capa.max_remain_on_chan)
drv->capa.max_remain_on_chan = 5000;
+ if (info->channel_switch_supported)
+ drv->capa.flags |= WPA_DRIVER_FLAGS_AP_CSA;
+
return 0;
nla_put_failure:
nlmsg_free(msg);
@@ -3496,15 +3688,10 @@
return -1;
drv->has_capability = 1;
- /* For now, assume TKIP, CCMP, WPA, WPA2 are supported */
drv->capa.key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA |
WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK;
- drv->capa.enc = WPA_DRIVER_CAPA_ENC_WEP40 |
- WPA_DRIVER_CAPA_ENC_WEP104 |
- WPA_DRIVER_CAPA_ENC_TKIP |
- WPA_DRIVER_CAPA_ENC_CCMP;
drv->capa.auth = WPA_DRIVER_AUTH_OPEN |
WPA_DRIVER_AUTH_SHARED |
WPA_DRIVER_AUTH_LEAP;
@@ -3526,7 +3713,8 @@
drv->device_ap_sme = info.device_ap_sme;
drv->poll_command_supported = info.poll_command_supported;
drv->data_tx_status = info.data_tx_status;
- drv->channel_switch_supported = info.channel_switch_supported;
+ if (info.set_qos_map_supported)
+ drv->capa.flags |= WPA_DRIVER_FLAGS_QOS_MAPPING;
/*
* If poll command and tx status are supported, mac80211 is new enough
@@ -3652,6 +3840,16 @@
/* Continue without regulatory events */
}
+ ret = nl_get_multicast_id(global, "nl80211", "vendor");
+ if (ret >= 0)
+ ret = nl_socket_add_membership(global->nl_event, ret);
+ if (ret < 0) {
+ wpa_printf(MSG_DEBUG, "nl80211: Could not add multicast "
+ "membership for vendor events: %d (%s)",
+ ret, strerror(-ret));
+ /* Continue without vendor events */
+ }
+
nl_cb_set(global->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
no_seq_check, NULL);
nl_cb_set(global->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
@@ -3912,15 +4110,16 @@
struct wpa_driver_nl80211_data *drv = bss->drv;
struct nl_msg *msg;
int ret = -1;
+ char buf[30];
msg = nlmsg_alloc();
if (!msg)
return -1;
- wpa_printf(MSG_DEBUG, "nl80211: Register frame type=0x%x nl_handle=%p",
- type, nl_handle);
- wpa_hexdump(MSG_DEBUG, "nl80211: Register frame match",
- match, match_len);
+ buf[0] = '\0';
+ wpa_snprintf_hex(buf, sizeof(buf), match, match_len);
+ wpa_printf(MSG_DEBUG, "nl80211: Register frame type=0x%x nl_handle=%p match=%s",
+ type, nl_handle, buf);
nl80211_cmd(drv, msg, 0, NL80211_CMD_REGISTER_ACTION);
@@ -3985,6 +4184,7 @@
static int nl80211_mgmt_subscribe_non_ap(struct i802_bss *bss)
{
struct wpa_driver_nl80211_data *drv = bss->drv;
+ int ret = 0;
if (nl80211_alloc_mgmt_handle(bss))
return -1;
@@ -4001,65 +4201,65 @@
#ifdef CONFIG_INTERWORKING
/* QoS Map Configure */
if (nl80211_register_action_frame(bss, (u8 *) "\x01\x04", 2) < 0)
- return -1;
+ ret = -1;
#endif /* CONFIG_INTERWORKING */
#if defined(CONFIG_P2P) || defined(CONFIG_INTERWORKING)
/* GAS Initial Request */
if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0a", 2) < 0)
- return -1;
+ ret = -1;
/* GAS Initial Response */
if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0b", 2) < 0)
- return -1;
+ ret = -1;
/* GAS Comeback Request */
if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0c", 2) < 0)
- return -1;
+ ret = -1;
/* GAS Comeback Response */
if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0d", 2) < 0)
- return -1;
+ ret = -1;
#endif /* CONFIG_P2P || CONFIG_INTERWORKING */
#ifdef CONFIG_P2P
/* P2P Public Action */
if (nl80211_register_action_frame(bss,
(u8 *) "\x04\x09\x50\x6f\x9a\x09",
6) < 0)
- return -1;
+ ret = -1;
/* P2P Action */
if (nl80211_register_action_frame(bss,
(u8 *) "\x7f\x50\x6f\x9a\x09",
5) < 0)
- return -1;
+ ret = -1;
#endif /* CONFIG_P2P */
#ifdef CONFIG_IEEE80211W
/* SA Query Response */
if (nl80211_register_action_frame(bss, (u8 *) "\x08\x01", 2) < 0)
- return -1;
+ ret = -1;
#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_TDLS
if ((drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT)) {
/* TDLS Discovery Response */
if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0e", 2) <
0)
- return -1;
+ ret = -1;
}
#endif /* CONFIG_TDLS */
/* FT Action frames */
if (nl80211_register_action_frame(bss, (u8 *) "\x06", 1) < 0)
- return -1;
+ ret = -1;
else
drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT |
WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK;
/* WNM - BSS Transition Management Request */
if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x07", 2) < 0)
- return -1;
+ ret = -1;
/* WNM-Sleep Mode Response */
if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x11", 2) < 0)
- return -1;
+ ret = -1;
nl80211_mgmt_handle_register_eloop(bss);
- return 0;
+ return ret;
}
@@ -4521,6 +4721,12 @@
params->filter_ssids = NULL;
drv->num_filter_ssids = params->num_filter_ssids;
+ if (params->only_new_results) {
+ wpa_printf(MSG_DEBUG, "nl80211: Add NL80211_SCAN_FLAG_FLUSH");
+ NLA_PUT_U32(msg, NL80211_ATTR_SCAN_FLAGS,
+ NL80211_SCAN_FLAG_FLUSH);
+ }
+
return msg;
fail:
@@ -4931,7 +5137,8 @@
* BSSID,SSID pair is seen on multiple channels. wpa_supplicant does
* not use frequency as a separate key in the BSS table, so filter out
* duplicated entries. Prefer associated BSS entry in such a case in
- * order to get the correct frequency into the BSS table.
+ * order to get the correct frequency into the BSS table. Similarly,
+ * prefer newer entries over older.
*/
for (i = 0; i < res->num; i++) {
const u8 *s1, *s2;
@@ -4949,8 +5156,9 @@
wpa_printf(MSG_DEBUG, "nl80211: Remove duplicated scan result "
"for " MACSTR, MAC2STR(r->bssid));
- if ((r->flags & WPA_SCAN_ASSOCIATED) &&
- !(res->res[i]->flags & WPA_SCAN_ASSOCIATED)) {
+ if (((r->flags & WPA_SCAN_ASSOCIATED) &&
+ !(res->res[i]->flags & WPA_SCAN_ASSOCIATED)) ||
+ r->age < res->res[i]->age) {
os_free(res->res[i]);
res->res[i] = r;
} else
@@ -5116,6 +5324,95 @@
}
+static u32 wpa_alg_to_cipher_suite(enum wpa_alg alg, size_t key_len)
+{
+ switch (alg) {
+ case WPA_ALG_WEP:
+ if (key_len == 5)
+ return WLAN_CIPHER_SUITE_WEP40;
+ return WLAN_CIPHER_SUITE_WEP104;
+ case WPA_ALG_TKIP:
+ return WLAN_CIPHER_SUITE_TKIP;
+ case WPA_ALG_CCMP:
+ return WLAN_CIPHER_SUITE_CCMP;
+ case WPA_ALG_GCMP:
+ return WLAN_CIPHER_SUITE_GCMP;
+ case WPA_ALG_CCMP_256:
+ return WLAN_CIPHER_SUITE_CCMP_256;
+ case WPA_ALG_GCMP_256:
+ return WLAN_CIPHER_SUITE_GCMP_256;
+ case WPA_ALG_IGTK:
+ return WLAN_CIPHER_SUITE_AES_CMAC;
+ case WPA_ALG_BIP_GMAC_128:
+ return WLAN_CIPHER_SUITE_BIP_GMAC_128;
+ case WPA_ALG_BIP_GMAC_256:
+ return WLAN_CIPHER_SUITE_BIP_GMAC_256;
+ case WPA_ALG_BIP_CMAC_256:
+ return WLAN_CIPHER_SUITE_BIP_CMAC_256;
+ case WPA_ALG_SMS4:
+ return WLAN_CIPHER_SUITE_SMS4;
+ case WPA_ALG_KRK:
+ return WLAN_CIPHER_SUITE_KRK;
+ case WPA_ALG_NONE:
+ case WPA_ALG_PMK:
+ wpa_printf(MSG_ERROR, "nl80211: Unexpected encryption algorithm %d",
+ alg);
+ return 0;
+ }
+
+ wpa_printf(MSG_ERROR, "nl80211: Unsupported encryption algorithm %d",
+ alg);
+ return 0;
+}
+
+
+static u32 wpa_cipher_to_cipher_suite(unsigned int cipher)
+{
+ switch (cipher) {
+ case WPA_CIPHER_CCMP_256:
+ return WLAN_CIPHER_SUITE_CCMP_256;
+ case WPA_CIPHER_GCMP_256:
+ return WLAN_CIPHER_SUITE_GCMP_256;
+ case WPA_CIPHER_CCMP:
+ return WLAN_CIPHER_SUITE_CCMP;
+ case WPA_CIPHER_GCMP:
+ return WLAN_CIPHER_SUITE_GCMP;
+ case WPA_CIPHER_TKIP:
+ return WLAN_CIPHER_SUITE_TKIP;
+ case WPA_CIPHER_WEP104:
+ return WLAN_CIPHER_SUITE_WEP104;
+ case WPA_CIPHER_WEP40:
+ return WLAN_CIPHER_SUITE_WEP40;
+ }
+
+ return 0;
+}
+
+
+static int wpa_cipher_to_cipher_suites(unsigned int ciphers, u32 suites[],
+ int max_suites)
+{
+ int num_suites = 0;
+
+ if (num_suites < max_suites && ciphers & WPA_CIPHER_CCMP_256)
+ suites[num_suites++] = WLAN_CIPHER_SUITE_CCMP_256;
+ if (num_suites < max_suites && ciphers & WPA_CIPHER_GCMP_256)
+ suites[num_suites++] = WLAN_CIPHER_SUITE_GCMP_256;
+ if (num_suites < max_suites && ciphers & WPA_CIPHER_CCMP)
+ suites[num_suites++] = WLAN_CIPHER_SUITE_CCMP;
+ if (num_suites < max_suites && ciphers & WPA_CIPHER_GCMP)
+ suites[num_suites++] = WLAN_CIPHER_SUITE_GCMP;
+ if (num_suites < max_suites && ciphers & WPA_CIPHER_TKIP)
+ suites[num_suites++] = WLAN_CIPHER_SUITE_TKIP;
+ if (num_suites < max_suites && ciphers & WPA_CIPHER_WEP104)
+ suites[num_suites++] = WLAN_CIPHER_SUITE_WEP104;
+ if (num_suites < max_suites && ciphers & WPA_CIPHER_WEP40)
+ suites[num_suites++] = WLAN_CIPHER_SUITE_WEP40;
+
+ return num_suites;
+}
+
+
static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
enum wpa_alg alg, const u8 *addr,
int key_idx, int set_tx,
@@ -5153,45 +5450,8 @@
} else {
nl80211_cmd(drv, msg, 0, NL80211_CMD_NEW_KEY);
NLA_PUT(msg, NL80211_ATTR_KEY_DATA, key_len, key);
- switch (alg) {
- case WPA_ALG_WEP:
- if (key_len == 5)
- NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
- WLAN_CIPHER_SUITE_WEP40);
- else
- NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
- WLAN_CIPHER_SUITE_WEP104);
- break;
- case WPA_ALG_TKIP:
- NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
- WLAN_CIPHER_SUITE_TKIP);
- break;
- case WPA_ALG_CCMP:
- NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
- WLAN_CIPHER_SUITE_CCMP);
- break;
- case WPA_ALG_GCMP:
- NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
- WLAN_CIPHER_SUITE_GCMP);
- break;
- case WPA_ALG_IGTK:
- NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
- WLAN_CIPHER_SUITE_AES_CMAC);
- break;
- case WPA_ALG_SMS4:
- NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
- WLAN_CIPHER_SUITE_SMS4);
- break;
- case WPA_ALG_KRK:
- NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
- WLAN_CIPHER_SUITE_KRK);
- break;
- default:
- wpa_printf(MSG_ERROR, "%s: Unsupported encryption "
- "algorithm %d", __func__, alg);
- nlmsg_free(msg);
- return -1;
- }
+ NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
+ wpa_alg_to_cipher_suite(alg, key_len));
}
if (seq && seq_len)
@@ -5296,33 +5556,8 @@
NLA_PUT_U8(msg, NL80211_KEY_IDX, key_idx);
- switch (alg) {
- case WPA_ALG_WEP:
- if (key_len == 5)
- NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
- WLAN_CIPHER_SUITE_WEP40);
- else
- NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
- WLAN_CIPHER_SUITE_WEP104);
- break;
- case WPA_ALG_TKIP:
- NLA_PUT_U32(msg, NL80211_KEY_CIPHER, WLAN_CIPHER_SUITE_TKIP);
- break;
- case WPA_ALG_CCMP:
- NLA_PUT_U32(msg, NL80211_KEY_CIPHER, WLAN_CIPHER_SUITE_CCMP);
- break;
- case WPA_ALG_GCMP:
- NLA_PUT_U32(msg, NL80211_KEY_CIPHER, WLAN_CIPHER_SUITE_GCMP);
- break;
- case WPA_ALG_IGTK:
- NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
- WLAN_CIPHER_SUITE_AES_CMAC);
- break;
- default:
- wpa_printf(MSG_ERROR, "%s: Unsupported encryption "
- "algorithm %d", __func__, alg);
- return -1;
- }
+ NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
+ wpa_alg_to_cipher_suite(alg, key_len));
if (seq && seq_len)
NLA_PUT(msg, NL80211_KEY_SEQ, seq_len, seq);
@@ -5784,10 +6019,8 @@
if (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED])
chan->flag |= HOSTAPD_CHAN_DISABLED;
- if (tb_freq[NL80211_FREQUENCY_ATTR_PASSIVE_SCAN])
- chan->flag |= HOSTAPD_CHAN_PASSIVE_SCAN;
- if (tb_freq[NL80211_FREQUENCY_ATTR_NO_IBSS])
- chan->flag |= HOSTAPD_CHAN_NO_IBSS;
+ if (tb_freq[NL80211_FREQUENCY_ATTR_NO_IR])
+ chan->flag |= HOSTAPD_CHAN_PASSIVE_SCAN | HOSTAPD_CHAN_NO_IBSS;
if (tb_freq[NL80211_FREQUENCY_ATTR_RADAR])
chan->flag |= HOSTAPD_CHAN_RADAR;
@@ -5816,8 +6049,7 @@
static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
[NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 },
[NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG },
- [NL80211_FREQUENCY_ATTR_PASSIVE_SCAN] = { .type = NLA_FLAG },
- [NL80211_FREQUENCY_ATTR_NO_IBSS] = { .type = NLA_FLAG },
+ [NL80211_FREQUENCY_ATTR_NO_IR] = { .type = NLA_FLAG },
[NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG },
[NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32 },
[NL80211_FREQUENCY_ATTR_DFS_STATE] = { .type = NLA_U32 },
@@ -6113,24 +6345,11 @@
}
-static void nl80211_reg_rule_max_eirp(struct nlattr *tb[],
+static void nl80211_reg_rule_max_eirp(u32 start, u32 end, u32 max_eirp,
struct phy_info_arg *results)
{
- u32 start, end, max_eirp;
u16 m;
- if (tb[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
- tb[NL80211_ATTR_FREQ_RANGE_END] == NULL ||
- tb[NL80211_ATTR_POWER_RULE_MAX_EIRP] == NULL)
- return;
-
- start = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
- end = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
- max_eirp = nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]) / 100;
-
- wpa_printf(MSG_DEBUG, "nl80211: %u-%u @ %u mBm",
- start, end, max_eirp);
-
for (m = 0; m < *results->num_modes; m++) {
int c;
struct hostapd_hw_modes *mode = &results->modes[m];
@@ -6145,26 +6364,11 @@
}
-static void nl80211_reg_rule_ht40(struct nlattr *tb[],
+static void nl80211_reg_rule_ht40(u32 start, u32 end,
struct phy_info_arg *results)
{
- u32 start, end, max_bw;
u16 m;
- if (tb[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
- tb[NL80211_ATTR_FREQ_RANGE_END] == NULL ||
- tb[NL80211_ATTR_FREQ_RANGE_MAX_BW] == NULL)
- return;
-
- start = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
- end = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
- max_bw = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
-
- wpa_printf(MSG_DEBUG, "nl80211: %u-%u @ %u MHz",
- start, end, max_bw);
- if (max_bw < 40)
- return;
-
for (m = 0; m < *results->num_modes; m++) {
if (!(results->modes[m].ht_capab &
HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
@@ -6285,10 +6489,26 @@
nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
{
+ u32 start, end, max_eirp = 0, max_bw = 0;
nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
nla_data(nl_rule), nla_len(nl_rule), reg_policy);
- nl80211_reg_rule_ht40(tb_rule, results);
- nl80211_reg_rule_max_eirp(tb_rule, results);
+ if (tb_rule[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
+ tb_rule[NL80211_ATTR_FREQ_RANGE_END] == NULL)
+ continue;
+ start = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
+ end = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
+ if (tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP])
+ max_eirp = nla_get_u32(tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP]) / 100;
+ if (tb_rule[NL80211_ATTR_FREQ_RANGE_MAX_BW])
+ max_bw = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
+
+ wpa_printf(MSG_DEBUG, "nl80211: %u-%u @ %u MHz %u mBm",
+ start, end, max_bw, max_eirp);
+ if (max_bw >= 40)
+ nl80211_reg_rule_ht40(start, end, results);
+ if (tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP])
+ nl80211_reg_rule_max_eirp(start, end, max_eirp,
+ results);
}
nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
@@ -6648,7 +6868,7 @@
int beacon_set;
int ifindex = if_nametoindex(bss->ifname);
int num_suites;
- u32 suites[10];
+ u32 suites[10], suite;
u32 ver;
beacon_set = bss->beacon_set;
@@ -6743,17 +6963,8 @@
wpa_printf(MSG_DEBUG, "nl80211: pairwise_ciphers=0x%x",
params->pairwise_ciphers);
- num_suites = 0;
- if (params->pairwise_ciphers & WPA_CIPHER_CCMP)
- suites[num_suites++] = WLAN_CIPHER_SUITE_CCMP;
- if (params->pairwise_ciphers & WPA_CIPHER_GCMP)
- suites[num_suites++] = WLAN_CIPHER_SUITE_GCMP;
- if (params->pairwise_ciphers & WPA_CIPHER_TKIP)
- suites[num_suites++] = WLAN_CIPHER_SUITE_TKIP;
- if (params->pairwise_ciphers & WPA_CIPHER_WEP104)
- suites[num_suites++] = WLAN_CIPHER_SUITE_WEP104;
- if (params->pairwise_ciphers & WPA_CIPHER_WEP40)
- suites[num_suites++] = WLAN_CIPHER_SUITE_WEP40;
+ num_suites = wpa_cipher_to_cipher_suites(params->pairwise_ciphers,
+ suites, ARRAY_SIZE(suites));
if (num_suites) {
NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
num_suites * sizeof(u32), suites);
@@ -6761,28 +6972,9 @@
wpa_printf(MSG_DEBUG, "nl80211: group_cipher=0x%x",
params->group_cipher);
- switch (params->group_cipher) {
- case WPA_CIPHER_CCMP:
- NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP,
- WLAN_CIPHER_SUITE_CCMP);
- break;
- case WPA_CIPHER_GCMP:
- NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP,
- WLAN_CIPHER_SUITE_GCMP);
- break;
- case WPA_CIPHER_TKIP:
- NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP,
- WLAN_CIPHER_SUITE_TKIP);
- break;
- case WPA_CIPHER_WEP104:
- NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP,
- WLAN_CIPHER_SUITE_WEP104);
- break;
- case WPA_CIPHER_WEP40:
- NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP,
- WLAN_CIPHER_SUITE_WEP40);
- break;
- }
+ suite = wpa_cipher_to_cipher_suite(params->group_cipher);
+ if (suite)
+ NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, suite);
if (params->beacon_ies) {
wpa_hexdump_buf(MSG_DEBUG, "nl80211: beacon_ies",
@@ -7977,10 +8169,10 @@
NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
}
- if (params->key_mgmt_suite == KEY_MGMT_802_1X ||
- params->key_mgmt_suite == KEY_MGMT_PSK ||
- params->key_mgmt_suite == KEY_MGMT_802_1X_SHA256 ||
- params->key_mgmt_suite == KEY_MGMT_PSK_SHA256) {
+ if (params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
+ params->key_mgmt_suite == WPA_KEY_MGMT_PSK ||
+ params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
+ params->key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256) {
wpa_printf(MSG_DEBUG, " * control port");
NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT);
}
@@ -8018,40 +8210,32 @@
}
-static int wpa_driver_nl80211_try_connect(
- struct wpa_driver_nl80211_data *drv,
- struct wpa_driver_associate_params *params)
+static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
+ struct wpa_driver_associate_params *params,
+ struct nl_msg *msg)
{
- struct nl_msg *msg;
- enum nl80211_auth_type type;
- int ret = 0;
- int algs;
-
- msg = nlmsg_alloc();
- if (!msg)
- return -1;
-
- wpa_printf(MSG_DEBUG, "nl80211: Connect (ifindex=%d)", drv->ifindex);
- nl80211_cmd(drv, msg, 0, NL80211_CMD_CONNECT);
-
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
+
if (params->bssid) {
wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
MAC2STR(params->bssid));
NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
}
+
if (params->freq) {
wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
drv->assoc_freq = params->freq;
} else
drv->assoc_freq = 0;
+
if (params->bg_scan_period >= 0) {
wpa_printf(MSG_DEBUG, " * bg scan period=%d",
params->bg_scan_period);
NLA_PUT_U16(msg, NL80211_ATTR_BG_SCAN_PERIOD,
params->bg_scan_period);
}
+
if (params->ssid) {
wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
params->ssid, params->ssid_len);
@@ -8062,11 +8246,122 @@
os_memcpy(drv->ssid, params->ssid, params->ssid_len);
drv->ssid_len = params->ssid_len;
}
+
wpa_hexdump(MSG_DEBUG, " * IEs", params->wpa_ie, params->wpa_ie_len);
if (params->wpa_ie)
NLA_PUT(msg, NL80211_ATTR_IE, params->wpa_ie_len,
params->wpa_ie);
+ if (params->wpa_proto) {
+ enum nl80211_wpa_versions ver = 0;
+
+ if (params->wpa_proto & WPA_PROTO_WPA)
+ ver |= NL80211_WPA_VERSION_1;
+ if (params->wpa_proto & WPA_PROTO_RSN)
+ ver |= NL80211_WPA_VERSION_2;
+
+ wpa_printf(MSG_DEBUG, " * WPA Versions 0x%x", ver);
+ NLA_PUT_U32(msg, NL80211_ATTR_WPA_VERSIONS, ver);
+ }
+
+ if (params->pairwise_suite != WPA_CIPHER_NONE) {
+ u32 cipher = wpa_cipher_to_cipher_suite(params->pairwise_suite);
+ wpa_printf(MSG_DEBUG, " * pairwise=0x%x", cipher);
+ NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE, cipher);
+ }
+
+ if (params->group_suite != WPA_CIPHER_NONE) {
+ u32 cipher = wpa_cipher_to_cipher_suite(params->group_suite);
+ wpa_printf(MSG_DEBUG, " * group=0x%x", cipher);
+ NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, cipher);
+ }
+
+ if (params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
+ params->key_mgmt_suite == WPA_KEY_MGMT_PSK ||
+ params->key_mgmt_suite == WPA_KEY_MGMT_FT_IEEE8021X ||
+ params->key_mgmt_suite == WPA_KEY_MGMT_FT_PSK ||
+ params->key_mgmt_suite == WPA_KEY_MGMT_CCKM) {
+ int mgmt = WLAN_AKM_SUITE_PSK;
+
+ switch (params->key_mgmt_suite) {
+ case WPA_KEY_MGMT_CCKM:
+ mgmt = WLAN_AKM_SUITE_CCKM;
+ break;
+ case WPA_KEY_MGMT_IEEE8021X:
+ mgmt = WLAN_AKM_SUITE_8021X;
+ break;
+ case WPA_KEY_MGMT_FT_IEEE8021X:
+ mgmt = WLAN_AKM_SUITE_FT_8021X;
+ break;
+ case WPA_KEY_MGMT_FT_PSK:
+ mgmt = WLAN_AKM_SUITE_FT_PSK;
+ break;
+ case WPA_KEY_MGMT_PSK:
+ default:
+ mgmt = WLAN_AKM_SUITE_PSK;
+ break;
+ }
+ NLA_PUT_U32(msg, NL80211_ATTR_AKM_SUITES, mgmt);
+ }
+
+ NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT);
+
+ if (params->mgmt_frame_protection == MGMT_FRAME_PROTECTION_REQUIRED)
+ NLA_PUT_U32(msg, NL80211_ATTR_USE_MFP, NL80211_MFP_REQUIRED);
+
+ if (params->disable_ht)
+ NLA_PUT_FLAG(msg, NL80211_ATTR_DISABLE_HT);
+
+ if (params->htcaps && params->htcaps_mask) {
+ int sz = sizeof(struct ieee80211_ht_capabilities);
+ NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY, sz, params->htcaps);
+ NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY_MASK, sz,
+ params->htcaps_mask);
+ }
+
+#ifdef CONFIG_VHT_OVERRIDES
+ if (params->disable_vht) {
+ wpa_printf(MSG_DEBUG, " * VHT disabled");
+ NLA_PUT_FLAG(msg, NL80211_ATTR_DISABLE_VHT);
+ }
+
+ if (params->vhtcaps && params->vhtcaps_mask) {
+ int sz = sizeof(struct ieee80211_vht_capabilities);
+ NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY, sz, params->vhtcaps);
+ NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY_MASK, sz,
+ params->vhtcaps_mask);
+ }
+#endif /* CONFIG_VHT_OVERRIDES */
+
+ if (params->p2p)
+ wpa_printf(MSG_DEBUG, " * P2P group");
+
+ return 0;
+nla_put_failure:
+ return -1;
+}
+
+
+static int wpa_driver_nl80211_try_connect(
+ struct wpa_driver_nl80211_data *drv,
+ struct wpa_driver_associate_params *params)
+{
+ struct nl_msg *msg;
+ enum nl80211_auth_type type;
+ int ret;
+ int algs;
+
+ msg = nlmsg_alloc();
+ if (!msg)
+ return -1;
+
+ wpa_printf(MSG_DEBUG, "nl80211: Connect (ifindex=%d)", drv->ifindex);
+ nl80211_cmd(drv, msg, 0, NL80211_CMD_CONNECT);
+
+ ret = nl80211_connect_common(drv, params, msg);
+ if (ret)
+ goto nla_put_failure;
+
algs = 0;
if (params->auth_alg & WPA_AUTH_ALG_OPEN)
algs++;
@@ -8095,129 +8390,6 @@
NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, type);
skip_auth_type:
- if (params->wpa_proto) {
- enum nl80211_wpa_versions ver = 0;
-
- if (params->wpa_proto & WPA_PROTO_WPA)
- ver |= NL80211_WPA_VERSION_1;
- if (params->wpa_proto & WPA_PROTO_RSN)
- ver |= NL80211_WPA_VERSION_2;
-
- wpa_printf(MSG_DEBUG, " * WPA Versions 0x%x", ver);
- NLA_PUT_U32(msg, NL80211_ATTR_WPA_VERSIONS, ver);
- }
-
- if (params->pairwise_suite != CIPHER_NONE) {
- int cipher;
-
- switch (params->pairwise_suite) {
- case CIPHER_SMS4:
- cipher = WLAN_CIPHER_SUITE_SMS4;
- break;
- case CIPHER_WEP40:
- cipher = WLAN_CIPHER_SUITE_WEP40;
- break;
- case CIPHER_WEP104:
- cipher = WLAN_CIPHER_SUITE_WEP104;
- break;
- case CIPHER_CCMP:
- cipher = WLAN_CIPHER_SUITE_CCMP;
- break;
- case CIPHER_GCMP:
- cipher = WLAN_CIPHER_SUITE_GCMP;
- break;
- case CIPHER_TKIP:
- default:
- cipher = WLAN_CIPHER_SUITE_TKIP;
- break;
- }
- NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE, cipher);
- }
-
- if (params->group_suite != CIPHER_NONE) {
- int cipher;
-
- switch (params->group_suite) {
- case CIPHER_SMS4:
- cipher = WLAN_CIPHER_SUITE_SMS4;
- break;
- case CIPHER_WEP40:
- cipher = WLAN_CIPHER_SUITE_WEP40;
- break;
- case CIPHER_WEP104:
- cipher = WLAN_CIPHER_SUITE_WEP104;
- break;
- case CIPHER_CCMP:
- cipher = WLAN_CIPHER_SUITE_CCMP;
- break;
- case CIPHER_GCMP:
- cipher = WLAN_CIPHER_SUITE_GCMP;
- break;
- case CIPHER_TKIP:
- default:
- cipher = WLAN_CIPHER_SUITE_TKIP;
- break;
- }
- NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, cipher);
- }
-
- if (params->key_mgmt_suite == KEY_MGMT_802_1X ||
- params->key_mgmt_suite == KEY_MGMT_PSK ||
- params->key_mgmt_suite == KEY_MGMT_FT_802_1X ||
- params->key_mgmt_suite == KEY_MGMT_FT_PSK ||
- params->key_mgmt_suite == KEY_MGMT_CCKM) {
- int mgmt = WLAN_AKM_SUITE_PSK;
-
- switch (params->key_mgmt_suite) {
- case KEY_MGMT_CCKM:
- mgmt = WLAN_AKM_SUITE_CCKM;
- break;
- case KEY_MGMT_802_1X:
- mgmt = WLAN_AKM_SUITE_8021X;
- break;
- case KEY_MGMT_FT_802_1X:
- mgmt = WLAN_AKM_SUITE_FT_8021X;
- break;
- case KEY_MGMT_FT_PSK:
- mgmt = WLAN_AKM_SUITE_FT_PSK;
- break;
- case KEY_MGMT_PSK:
- default:
- mgmt = WLAN_AKM_SUITE_PSK;
- break;
- }
- NLA_PUT_U32(msg, NL80211_ATTR_AKM_SUITES, mgmt);
- }
-
-#ifdef CONFIG_IEEE80211W
- if (params->mgmt_frame_protection == MGMT_FRAME_PROTECTION_REQUIRED)
- NLA_PUT_U32(msg, NL80211_ATTR_USE_MFP, NL80211_MFP_REQUIRED);
-#endif /* CONFIG_IEEE80211W */
-
- if (params->disable_ht)
- NLA_PUT_FLAG(msg, NL80211_ATTR_DISABLE_HT);
-
- if (params->htcaps && params->htcaps_mask) {
- int sz = sizeof(struct ieee80211_ht_capabilities);
- NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY, sz, params->htcaps);
- NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY_MASK, sz,
- params->htcaps_mask);
- }
-
-#ifdef CONFIG_VHT_OVERRIDES
- if (params->disable_vht) {
- wpa_printf(MSG_DEBUG, " * VHT disabled");
- NLA_PUT_FLAG(msg, NL80211_ATTR_DISABLE_VHT);
- }
-
- if (params->vhtcaps && params->vhtcaps_mask) {
- int sz = sizeof(struct ieee80211_vht_capabilities);
- NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY, sz, params->vhtcaps);
- NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY_MASK, sz,
- params->vhtcaps_mask);
- }
-#endif /* CONFIG_VHT_OVERRIDES */
-
ret = nl80211_set_conn_keys(params, msg);
if (ret)
goto nla_put_failure;
@@ -8267,7 +8439,7 @@
{
struct i802_bss *bss = priv;
struct wpa_driver_nl80211_data *drv = bss->drv;
- int ret = -1;
+ int ret;
struct nl_msg *msg;
if (params->mode == IEEE80211_MODE_AP)
@@ -8295,95 +8467,9 @@
drv->ifindex);
nl80211_cmd(drv, msg, 0, NL80211_CMD_ASSOCIATE);
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
- if (params->bssid) {
- wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
- MAC2STR(params->bssid));
- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
- }
- if (params->freq) {
- wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
- drv->assoc_freq = params->freq;
- } else
- drv->assoc_freq = 0;
- if (params->bg_scan_period >= 0) {
- wpa_printf(MSG_DEBUG, " * bg scan period=%d",
- params->bg_scan_period);
- NLA_PUT_U16(msg, NL80211_ATTR_BG_SCAN_PERIOD,
- params->bg_scan_period);
- }
- if (params->ssid) {
- wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
- params->ssid, params->ssid_len);
- NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
- params->ssid);
- if (params->ssid_len > sizeof(drv->ssid))
- goto nla_put_failure;
- os_memcpy(drv->ssid, params->ssid, params->ssid_len);
- drv->ssid_len = params->ssid_len;
- }
- wpa_hexdump(MSG_DEBUG, " * IEs", params->wpa_ie, params->wpa_ie_len);
- if (params->wpa_ie)
- NLA_PUT(msg, NL80211_ATTR_IE, params->wpa_ie_len,
- params->wpa_ie);
-
- if (params->pairwise_suite != CIPHER_NONE) {
- int cipher;
-
- switch (params->pairwise_suite) {
- case CIPHER_WEP40:
- cipher = WLAN_CIPHER_SUITE_WEP40;
- break;
- case CIPHER_WEP104:
- cipher = WLAN_CIPHER_SUITE_WEP104;
- break;
- case CIPHER_CCMP:
- cipher = WLAN_CIPHER_SUITE_CCMP;
- break;
- case CIPHER_GCMP:
- cipher = WLAN_CIPHER_SUITE_GCMP;
- break;
- case CIPHER_TKIP:
- default:
- cipher = WLAN_CIPHER_SUITE_TKIP;
- break;
- }
- wpa_printf(MSG_DEBUG, " * pairwise=0x%x", cipher);
- NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE, cipher);
- }
-
- if (params->group_suite != CIPHER_NONE) {
- int cipher;
-
- switch (params->group_suite) {
- case CIPHER_WEP40:
- cipher = WLAN_CIPHER_SUITE_WEP40;
- break;
- case CIPHER_WEP104:
- cipher = WLAN_CIPHER_SUITE_WEP104;
- break;
- case CIPHER_CCMP:
- cipher = WLAN_CIPHER_SUITE_CCMP;
- break;
- case CIPHER_GCMP:
- cipher = WLAN_CIPHER_SUITE_GCMP;
- break;
- case CIPHER_TKIP:
- default:
- cipher = WLAN_CIPHER_SUITE_TKIP;
- break;
- }
- wpa_printf(MSG_DEBUG, " * group=0x%x", cipher);
- NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, cipher);
- }
-
-#ifdef CONFIG_IEEE80211W
- if (params->mgmt_frame_protection == MGMT_FRAME_PROTECTION_REQUIRED)
- NLA_PUT_U32(msg, NL80211_ATTR_USE_MFP, NL80211_MFP_REQUIRED);
-#endif /* CONFIG_IEEE80211W */
-
- NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT);
+ ret = nl80211_connect_common(drv, params, msg);
+ if (ret)
+ goto nla_put_failure;
if (params->prev_bssid) {
wpa_printf(MSG_DEBUG, " * prev_bssid=" MACSTR,
@@ -8392,33 +8478,6 @@
params->prev_bssid);
}
- if (params->disable_ht)
- NLA_PUT_FLAG(msg, NL80211_ATTR_DISABLE_HT);
-
- if (params->htcaps && params->htcaps_mask) {
- int sz = sizeof(struct ieee80211_ht_capabilities);
- NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY, sz, params->htcaps);
- NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY_MASK, sz,
- params->htcaps_mask);
- }
-
-#ifdef CONFIG_VHT_OVERRIDES
- if (params->disable_vht) {
- wpa_printf(MSG_DEBUG, " * VHT disabled");
- NLA_PUT_FLAG(msg, NL80211_ATTR_DISABLE_VHT);
- }
-
- if (params->vhtcaps && params->vhtcaps_mask) {
- int sz = sizeof(struct ieee80211_vht_capabilities);
- NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY, sz, params->vhtcaps);
- NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY_MASK, sz,
- params->vhtcaps_mask);
- }
-#endif /* CONFIG_VHT_OVERRIDES */
-
- if (params->p2p)
- wpa_printf(MSG_DEBUG, " * P2P group");
-
ret = send_and_recv_msgs(drv, msg, NULL, NULL);
msg = NULL;
if (ret) {
@@ -8593,8 +8652,9 @@
struct i802_bss *bss = priv;
struct wpa_driver_nl80211_data *drv = bss->drv;
- wpa_printf(MSG_DEBUG, "%s: operstate %d->%d (%s)",
- __func__, drv->operstate, state, state ? "UP" : "DORMANT");
+ wpa_printf(MSG_DEBUG, "nl80211: Set %s operstate %d->%d (%s)",
+ bss->ifname, drv->operstate, state,
+ state ? "UP" : "DORMANT");
drv->operstate = state;
return netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, -1,
state ? IF_OPER_UP : IF_OPER_DORMANT);
@@ -8607,6 +8667,12 @@
struct wpa_driver_nl80211_data *drv = bss->drv;
struct nl_msg *msg;
struct nl80211_sta_flag_update upd;
+ int ret = -ENOBUFS;
+
+ if (!drv->associated && is_zero_ether_addr(drv->bssid) && !authorized) {
+ wpa_printf(MSG_DEBUG, "nl80211: Skip set_supp_port(unauthorized) while not associated");
+ return 0;
+ }
wpa_printf(MSG_DEBUG, "nl80211: Set supplicant port %sauthorized for "
MACSTR, authorized ? "" : "un", MAC2STR(drv->bssid));
@@ -8627,10 +8693,15 @@
upd.set = BIT(NL80211_STA_FLAG_AUTHORIZED);
NLA_PUT(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd);
- return send_and_recv_msgs(drv, msg, NULL, NULL);
+ ret = send_and_recv_msgs(drv, msg, NULL, NULL);
+ msg = NULL;
+ if (!ret)
+ return 0;
nla_put_failure:
nlmsg_free(msg);
- return -ENOBUFS;
+ wpa_printf(MSG_DEBUG, "nl80211: Failed to set STA flag: %d (%s)",
+ ret, strerror(-ret));
+ return ret;
}
@@ -10209,6 +10280,18 @@
}
#endif /* CONFIG_P2P */
+ if (os_strstr(param, "use_monitor=1")) {
+ struct i802_bss *bss = priv;
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+ drv->use_monitor = 1;
+ }
+
+ if (os_strstr(param, "force_connect_cmd=1")) {
+ struct i802_bss *bss = priv;
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+ drv->capa.flags &= ~WPA_DRIVER_FLAGS_SME;
+ }
+
return 0;
}
@@ -11321,7 +11404,7 @@
settings->freq_params.center_freq1,
settings->freq_params.center_freq2);
- if (!drv->channel_switch_supported) {
+ if (!(drv->capa.flags & WPA_DRIVER_FLAGS_AP_CSA)) {
wpa_printf(MSG_DEBUG, "nl80211: Driver does not support channel switch command");
return -EOPNOTSUPP;
}
@@ -11397,6 +11480,37 @@
}
+static int nl80211_set_qos_map(void *priv, const u8 *qos_map_set,
+ u8 qos_map_set_len)
+{
+ struct i802_bss *bss = priv;
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+ struct nl_msg *msg;
+ int ret;
+
+ msg = nlmsg_alloc();
+ if (!msg)
+ return -ENOMEM;
+
+ wpa_hexdump(MSG_DEBUG, "nl80211: Setting QoS Map",
+ qos_map_set, qos_map_set_len);
+
+ nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_QOS_MAP);
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
+ NLA_PUT(msg, NL80211_ATTR_QOS_MAP, qos_map_set_len, qos_map_set);
+
+ ret = send_and_recv_msgs(drv, msg, NULL, NULL);
+ if (ret)
+ wpa_printf(MSG_DEBUG, "nl80211: Setting QoS Map failed");
+
+ return ret;
+
+nla_put_failure:
+ nlmsg_free(msg);
+ return -ENOBUFS;
+}
+
+
const struct wpa_driver_ops wpa_driver_nl80211_ops = {
.name = "nl80211",
.desc = "Linux nl80211/cfg80211",
@@ -11485,4 +11599,5 @@
#ifdef ANDROID
.driver_cmd = wpa_driver_nl80211_driver_cmd,
#endif /* ANDROID */
+ .set_qos_map = nl80211_set_qos_map,
};
diff --git a/src/drivers/driver_test.c b/src/drivers/driver_test.c
index 5742b98..7d30655 100644
--- a/src/drivers/driver_test.c
+++ b/src/drivers/driver_test.c
@@ -28,7 +28,6 @@
#include "common/ieee802_11_defs.h"
#include "crypto/sha1.h"
#include "l2_packet/l2_packet.h"
-#include "p2p/p2p.h"
#include "wps/wps.h"
#include "driver.h"
@@ -102,20 +101,6 @@
unsigned int remain_on_channel_duration;
int current_freq;
-
- struct p2p_data *p2p;
- unsigned int off_channel_freq;
- struct wpabuf *pending_action_tx;
- u8 pending_action_src[ETH_ALEN];
- u8 pending_action_dst[ETH_ALEN];
- u8 pending_action_bssid[ETH_ALEN];
- unsigned int pending_action_freq;
- unsigned int pending_action_no_cck;
- unsigned int pending_listen_freq;
- unsigned int pending_listen_duration;
- int pending_p2p_scan;
- struct sockaddr *probe_from;
- socklen_t probe_from_len;
};
@@ -125,7 +110,6 @@
static void wpa_driver_test_close_test_socket(
struct wpa_driver_test_data *drv);
static void test_remain_on_channel_timeout(void *eloop_ctx, void *timeout_ctx);
-static int wpa_driver_test_init_p2p(struct wpa_driver_test_data *drv);
static void test_driver_free_bss(struct test_driver_bss *bss)
@@ -479,34 +463,6 @@
event.tx_status.ack = ret >= 0;
wpa_supplicant_event(drv->ctx, EVENT_TX_STATUS, &event);
-#ifdef CONFIG_P2P
- if (drv->p2p &&
- WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
- WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION) {
- if (drv->pending_action_tx == NULL) {
- wpa_printf(MSG_DEBUG, "P2P: Ignore Action TX status - "
- "no pending operation");
- return ret;
- }
-
- if (os_memcmp(hdr->addr1, drv->pending_action_dst, ETH_ALEN) !=
- 0) {
- wpa_printf(MSG_DEBUG, "P2P: Ignore Action TX status - "
- "unknown destination address");
- return ret;
- }
-
- wpabuf_free(drv->pending_action_tx);
- drv->pending_action_tx = NULL;
-
- p2p_send_action_cb(drv->p2p, drv->pending_action_freq,
- drv->pending_action_dst,
- drv->pending_action_src,
- drv->pending_action_bssid,
- ret >= 0);
- }
-#endif /* CONFIG_P2P */
-
return ret;
}
@@ -553,10 +509,6 @@
event.rx_probe_req.ie = ie;
event.rx_probe_req.ie_len = ielen;
wpa_supplicant_event(drv->ctx, EVENT_RX_PROBE_REQ, &event);
-#ifdef CONFIG_P2P
- if (drv->p2p)
- p2p_probe_req_rx(drv->p2p, sa, NULL, NULL, ie, ielen);
-#endif /* CONFIG_P2P */
}
dl_list_for_each(bss, &drv->bss, struct test_driver_bss, list) {
@@ -1313,25 +1265,7 @@
static void wpa_driver_test_scan_timeout(void *eloop_ctx, void *timeout_ctx)
{
- struct wpa_driver_test_data *drv = eloop_ctx;
wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
- if (drv->pending_p2p_scan && drv->p2p) {
-#ifdef CONFIG_P2P
- size_t i;
- struct os_time now;
- os_get_time(&now);
- for (i = 0; i < drv->num_scanres; i++) {
- struct wpa_scan_res *bss = drv->scanres[i];
- if (p2p_scan_res_handler(drv->p2p, bss->bssid,
- bss->freq, &now, bss->level,
- (const u8 *) (bss + 1),
- bss->ie_len) > 0)
- return;
- }
- p2p_scan_res_handled(drv->p2p);
-#endif /* CONFIG_P2P */
- return;
- }
wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
}
@@ -1949,30 +1883,8 @@
data_len - (mgmt->u.probe_req.variable - data);
wpa_supplicant_event(drv->ctx, EVENT_RX_PROBE_REQ,
&event);
-#ifdef CONFIG_P2P
- if (drv->p2p)
- p2p_probe_req_rx(drv->p2p, mgmt->sa,
- mgmt->da, mgmt->bssid,
- event.rx_probe_req.ie,
- event.rx_probe_req.ie_len);
-#endif /* CONFIG_P2P */
}
}
-
-#ifdef CONFIG_P2P
- if (drv->p2p &&
- WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
- WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION) {
- size_t hdr_len;
- hdr_len = (const u8 *)
- &mgmt->u.action.u.vs_public_action.action - data;
- p2p_rx_action(drv->p2p, mgmt->da, mgmt->sa, mgmt->bssid,
- mgmt->u.action.category,
- &mgmt->u.action.u.vs_public_action.action,
- data_len - hdr_len, freq);
- }
-#endif /* CONFIG_P2P */
-
}
@@ -1988,29 +1900,6 @@
bss = dl_list_first(&drv->bss, struct test_driver_bss, list);
/* data: optional [ STA-addr | ' ' | IEs(hex) ] */
-#ifdef CONFIG_P2P
- if (drv->probe_req_report && drv->p2p && data_len) {
- const char *d = (const char *) data;
- u8 sa[ETH_ALEN];
- u8 ie[512];
- size_t ielen;
-
- if (hwaddr_aton(d, sa))
- return;
- d += 18;
- while (*d == ' ')
- d++;
- ielen = os_strlen(d) / 2;
- if (ielen > sizeof(ie))
- ielen = sizeof(ie);
- if (hexstr2bin(d, ie, ielen) < 0)
- ielen = 0;
- drv->probe_from = from;
- drv->probe_from_len = fromlen;
- p2p_probe_req_rx(drv->p2p, sa, NULL, NULL, ie, ielen);
- drv->probe_from = NULL;
- }
-#endif /* CONFIG_P2P */
if (!drv->ibss)
return;
@@ -2167,12 +2056,6 @@
struct test_client_socket *cli, *prev;
int i;
-#ifdef CONFIG_P2P
- if (drv->p2p)
- p2p_deinit(drv->p2p);
- wpabuf_free(drv->pending_action_tx);
-#endif /* CONFIG_P2P */
-
cli = drv->cli;
while (cli) {
prev = cli;
@@ -2369,13 +2252,6 @@
drv->use_associnfo = 1;
}
- if (os_strstr(param, "p2p_mgmt=1")) {
- wpa_printf(MSG_DEBUG, "test_driver: Use internal P2P "
- "management");
- if (wpa_driver_test_init_p2p(drv) < 0)
- return -1;
- }
-
return 0;
}
@@ -2465,8 +2341,6 @@
static int wpa_driver_test_get_capa(void *priv, struct wpa_driver_capa *capa)
{
- struct test_driver_bss *dbss = priv;
- struct wpa_driver_test_data *drv = dbss->drv;
os_memset(capa, 0, sizeof(*capa));
capa->key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA |
WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
@@ -2482,8 +2356,6 @@
capa->auth = WPA_DRIVER_AUTH_OPEN |
WPA_DRIVER_AUTH_SHARED |
WPA_DRIVER_AUTH_LEAP;
- if (drv->p2p)
- capa->flags |= WPA_DRIVER_FLAGS_P2P_MGMT;
capa->flags |= WPA_DRIVER_FLAGS_AP;
capa->flags |= WPA_DRIVER_FLAGS_P2P_CONCURRENT;
capa->flags |= WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE;
@@ -2691,33 +2563,6 @@
}
-#ifdef CONFIG_P2P
-static void test_send_action_cb(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_driver_test_data *drv = eloop_ctx;
-
- if (drv->pending_action_tx == NULL)
- return;
-
- if (drv->off_channel_freq != drv->pending_action_freq) {
- wpa_printf(MSG_DEBUG, "P2P: Pending Action frame TX "
- "waiting for another freq=%u",
- drv->pending_action_freq);
- return;
- }
- wpa_printf(MSG_DEBUG, "P2P: Sending pending Action frame to "
- MACSTR, MAC2STR(drv->pending_action_dst));
- wpa_driver_test_send_action(drv, drv->pending_action_freq, 0,
- drv->pending_action_dst,
- drv->pending_action_src,
- drv->pending_action_bssid,
- wpabuf_head(drv->pending_action_tx),
- wpabuf_len(drv->pending_action_tx),
- drv->pending_action_no_cck);
-}
-#endif /* CONFIG_P2P */
-
-
static void test_remain_on_channel_timeout(void *eloop_ctx, void *timeout_ctx)
{
struct wpa_driver_test_data *drv = eloop_ctx;
@@ -2729,9 +2574,6 @@
data.remain_on_channel.freq = drv->remain_on_channel_freq;
data.remain_on_channel.duration = drv->remain_on_channel_duration;
- if (drv->p2p)
- drv->off_channel_freq = 0;
-
drv->remain_on_channel_freq = 0;
wpa_supplicant_event(drv->ctx, EVENT_CANCEL_REMAIN_ON_CHANNEL, &data);
@@ -2765,18 +2607,6 @@
data.remain_on_channel.duration = duration;
wpa_supplicant_event(drv->ctx, EVENT_REMAIN_ON_CHANNEL, &data);
-#ifdef CONFIG_P2P
- if (drv->p2p) {
- drv->off_channel_freq = drv->remain_on_channel_freq;
- test_send_action_cb(drv, NULL);
- if (drv->off_channel_freq == drv->pending_listen_freq) {
- p2p_listen_cb(drv->p2p, drv->pending_listen_freq,
- drv->pending_listen_duration);
- drv->pending_listen_freq = 0;
- }
- }
-#endif /* CONFIG_P2P */
-
return 0;
}
@@ -2804,470 +2634,6 @@
}
-#ifdef CONFIG_P2P
-
-static int wpa_driver_test_p2p_find(void *priv, unsigned int timeout, int type)
-{
- struct test_driver_bss *dbss = priv;
- struct wpa_driver_test_data *drv = dbss->drv;
- wpa_printf(MSG_DEBUG, "%s(timeout=%u)", __func__, timeout);
- if (!drv->p2p)
- return -1;
- return p2p_find(drv->p2p, timeout, type, 0, NULL, NULL, 0);
-}
-
-
-static int wpa_driver_test_p2p_stop_find(void *priv)
-{
- struct test_driver_bss *dbss = priv;
- struct wpa_driver_test_data *drv = dbss->drv;
- wpa_printf(MSG_DEBUG, "%s", __func__);
- if (!drv->p2p)
- return -1;
- p2p_stop_find(drv->p2p);
- return 0;
-}
-
-
-static int wpa_driver_test_p2p_listen(void *priv, unsigned int timeout)
-{
- struct test_driver_bss *dbss = priv;
- struct wpa_driver_test_data *drv = dbss->drv;
- wpa_printf(MSG_DEBUG, "%s(timeout=%u)", __func__, timeout);
- if (!drv->p2p)
- return -1;
- return p2p_listen(drv->p2p, timeout);
-}
-
-
-static int wpa_driver_test_p2p_connect(void *priv, const u8 *peer_addr,
- int wps_method, int go_intent,
- const u8 *own_interface_addr,
- unsigned int force_freq,
- int persistent_group)
-{
- struct test_driver_bss *dbss = priv;
- struct wpa_driver_test_data *drv = dbss->drv;
- wpa_printf(MSG_DEBUG, "%s(peer_addr=" MACSTR " wps_method=%d "
- "go_intent=%d "
- "own_interface_addr=" MACSTR " force_freq=%u "
- "persistent_group=%d)",
- __func__, MAC2STR(peer_addr), wps_method, go_intent,
- MAC2STR(own_interface_addr), force_freq, persistent_group);
- if (!drv->p2p)
- return -1;
- return p2p_connect(drv->p2p, peer_addr, wps_method, go_intent,
- own_interface_addr, force_freq, persistent_group,
- NULL, 0, 0, 0);
-}
-
-
-static int wpa_driver_test_wps_success_cb(void *priv, const u8 *peer_addr)
-{
- struct test_driver_bss *dbss = priv;
- struct wpa_driver_test_data *drv = dbss->drv;
- wpa_printf(MSG_DEBUG, "%s(peer_addr=" MACSTR ")",
- __func__, MAC2STR(peer_addr));
- if (!drv->p2p)
- return -1;
- p2p_wps_success_cb(drv->p2p, peer_addr);
- return 0;
-}
-
-
-static int wpa_driver_test_p2p_group_formation_failed(void *priv)
-{
- struct test_driver_bss *dbss = priv;
- struct wpa_driver_test_data *drv = dbss->drv;
- wpa_printf(MSG_DEBUG, "%s", __func__);
- if (!drv->p2p)
- return -1;
- p2p_group_formation_failed(drv->p2p);
- return 0;
-}
-
-
-static int wpa_driver_test_p2p_set_params(void *priv,
- const struct p2p_params *params)
-{
- struct test_driver_bss *dbss = priv;
- struct wpa_driver_test_data *drv = dbss->drv;
- wpa_printf(MSG_DEBUG, "%s", __func__);
- if (!drv->p2p)
- return -1;
- if (p2p_set_dev_name(drv->p2p, params->dev_name) < 0 ||
- p2p_set_pri_dev_type(drv->p2p, params->pri_dev_type) < 0 ||
- p2p_set_sec_dev_types(drv->p2p, params->sec_dev_type,
- params->num_sec_dev_types) < 0)
- return -1;
- return 0;
-}
-
-
-static int test_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
- unsigned int num_req_dev_types,
- const u8 *req_dev_types, const u8 *dev_id, u16 pw_id)
-{
- struct wpa_driver_test_data *drv = ctx;
- struct wpa_driver_scan_params params;
- int ret;
- struct wpabuf *wps_ie, *ies;
- int social_channels[] = { 2412, 2437, 2462, 0, 0 };
- size_t ielen;
-
- wpa_printf(MSG_DEBUG, "%s(type=%d freq=%d)",
- __func__, type, freq);
-
- os_memset(¶ms, 0, sizeof(params));
-
- /* P2P Wildcard SSID */
- params.num_ssids = 1;
- params.ssids[0].ssid = (u8 *) P2P_WILDCARD_SSID;
- params.ssids[0].ssid_len = P2P_WILDCARD_SSID_LEN;
-
-#if 0 /* TODO: WPS IE */
- wpa_s->wps->dev.p2p = 1;
- wps_ie = wps_build_probe_req_ie(pw_id, &wpa_s->wps->dev,
- wpa_s->wps->uuid, WPS_REQ_ENROLLEE);
-#else
- wps_ie = wpabuf_alloc(1);
-#endif
- if (wps_ie == NULL)
- return -1;
-
- ielen = p2p_scan_ie_buf_len(drv->p2p);
- ies = wpabuf_alloc(wpabuf_len(wps_ie) + ielen);
- if (ies == NULL) {
- wpabuf_free(wps_ie);
- return -1;
- }
- wpabuf_put_buf(ies, wps_ie);
- wpabuf_free(wps_ie);
-
- p2p_scan_ie(drv->p2p, ies, dev_id);
-
- params.extra_ies = wpabuf_head(ies);
- params.extra_ies_len = wpabuf_len(ies);
-
- switch (type) {
- case P2P_SCAN_SOCIAL:
- params.freqs = social_channels;
- break;
- case P2P_SCAN_FULL:
- break;
- case P2P_SCAN_SOCIAL_PLUS_ONE:
- social_channels[3] = freq;
- params.freqs = social_channels;
- break;
- }
-
- drv->pending_p2p_scan = 1;
- ret = wpa_driver_test_scan(drv, ¶ms);
-
- wpabuf_free(ies);
-
- return ret;
-}
-
-
-static int test_send_action(void *ctx, unsigned int freq, const u8 *dst,
- const u8 *src, const u8 *bssid, const u8 *buf,
- size_t len, unsigned int wait_time)
-{
- struct wpa_driver_test_data *drv = ctx;
-
- wpa_printf(MSG_DEBUG, "%s(freq=%u dst=" MACSTR " src=" MACSTR
- " bssid=" MACSTR " len=%d",
- __func__, freq, MAC2STR(dst), MAC2STR(src), MAC2STR(bssid),
- (int) len);
- if (freq <= 0) {
- wpa_printf(MSG_WARNING, "P2P: No frequency specified for "
- "action frame TX");
- return -1;
- }
-
- if (drv->pending_action_tx) {
- wpa_printf(MSG_DEBUG, "P2P: Dropped pending Action frame TX "
- "to " MACSTR, MAC2STR(drv->pending_action_dst));
- wpabuf_free(drv->pending_action_tx);
- }
- drv->pending_action_tx = wpabuf_alloc(len);
- if (drv->pending_action_tx == NULL)
- return -1;
- wpabuf_put_data(drv->pending_action_tx, buf, len);
- os_memcpy(drv->pending_action_src, src, ETH_ALEN);
- os_memcpy(drv->pending_action_dst, dst, ETH_ALEN);
- os_memcpy(drv->pending_action_bssid, bssid, ETH_ALEN);
- drv->pending_action_freq = freq;
- drv->pending_action_no_cck = 1;
-
- if (drv->off_channel_freq == freq) {
- /* Already on requested channel; send immediately */
- /* TODO: Would there ever be need to extend the current
- * duration on the channel? */
- eloop_cancel_timeout(test_send_action_cb, drv, NULL);
- eloop_register_timeout(0, 0, test_send_action_cb, drv, NULL);
- return 0;
- }
-
- wpa_printf(MSG_DEBUG, "P2P: Schedule Action frame to be transmitted "
- "once the driver gets to the requested channel");
- if (wpa_driver_test_remain_on_channel(drv, freq, wait_time) < 0) {
- wpa_printf(MSG_DEBUG, "P2P: Failed to request driver "
- "to remain on channel (%u MHz) for Action "
- "Frame TX", freq);
- return -1;
- }
-
- return 0;
-}
-
-
-static void test_send_action_done(void *ctx)
-{
- wpa_printf(MSG_DEBUG, "%s", __func__);
- /* TODO */
-}
-
-
-static void test_go_neg_completed(void *ctx, struct p2p_go_neg_results *res)
-{
- struct wpa_driver_test_data *drv = ctx;
- union wpa_event_data event;
- wpa_printf(MSG_DEBUG, "%s", __func__);
- os_memset(&event, 0, sizeof(event));
- event.p2p_go_neg_completed.res = res;
- wpa_supplicant_event(drv->ctx, EVENT_P2P_GO_NEG_COMPLETED, &event);
-}
-
-
-static void test_go_neg_req_rx(void *ctx, const u8 *src, u16 dev_passwd_id)
-{
- struct wpa_driver_test_data *drv = ctx;
- union wpa_event_data event;
- wpa_printf(MSG_DEBUG, "%s(src=" MACSTR ")", __func__, MAC2STR(src));
- os_memset(&event, 0, sizeof(event));
- event.p2p_go_neg_req_rx.src = src;
- event.p2p_go_neg_req_rx.dev_passwd_id = dev_passwd_id;
- wpa_supplicant_event(drv->ctx, EVENT_P2P_GO_NEG_REQ_RX, &event);
-}
-
-
-static void test_dev_found(void *ctx, const u8 *addr,
- const struct p2p_peer_info *info, int new_device)
-{
- struct wpa_driver_test_data *drv = ctx;
- union wpa_event_data event;
- char devtype[WPS_DEV_TYPE_BUFSIZE];
- wpa_printf(MSG_DEBUG, "%s(" MACSTR " p2p_dev_addr=" MACSTR
- " pri_dev_type=%s name='%s' config_methods=0x%x "
- "dev_capab=0x%x group_capab=0x%x)",
- __func__, MAC2STR(addr), MAC2STR(info->p2p_device_addr),
- wps_dev_type_bin2str(info->pri_dev_type, devtype,
- sizeof(devtype)),
- info->device_name, info->config_methods, info->dev_capab,
- info->group_capab);
-
- os_memset(&event, 0, sizeof(event));
- event.p2p_dev_found.addr = addr;
- event.p2p_dev_found.dev_addr = info->p2p_device_addr;
- event.p2p_dev_found.pri_dev_type = info->pri_dev_type;
- event.p2p_dev_found.dev_name = info->device_name;
- event.p2p_dev_found.config_methods = info->config_methods;
- event.p2p_dev_found.dev_capab = info->dev_capab;
- event.p2p_dev_found.group_capab = info->group_capab;
- wpa_supplicant_event(drv->ctx, EVENT_P2P_DEV_FOUND, &event);
-}
-
-
-static int test_start_listen(void *ctx, unsigned int freq,
- unsigned int duration,
- const struct wpabuf *probe_resp_ie)
-{
- struct wpa_driver_test_data *drv = ctx;
-
- wpa_printf(MSG_DEBUG, "%s(freq=%u duration=%u)",
- __func__, freq, duration);
-
- if (wpa_driver_test_probe_req_report(drv, 1) < 0)
- return -1;
-
- drv->pending_listen_freq = freq;
- drv->pending_listen_duration = duration;
-
- if (wpa_driver_test_remain_on_channel(drv, freq, duration) < 0) {
- drv->pending_listen_freq = 0;
- return -1;
- }
-
- return 0;
-}
-
-
-static void test_stop_listen(void *ctx)
-{
- wpa_printf(MSG_DEBUG, "%s", __func__);
- /* TODO */
-}
-
-
-static int test_send_probe_resp(void *ctx, const struct wpabuf *buf)
-{
- struct wpa_driver_test_data *drv = ctx;
- char resp[512], *pos, *end;
- int ret;
- const struct ieee80211_mgmt *mgmt;
- const u8 *ie, *ie_end;
-
- wpa_printf(MSG_DEBUG, "%s", __func__);
- wpa_hexdump_buf(MSG_MSGDUMP, "Probe Response", buf);
- if (wpabuf_len(buf) < 24)
- return -1;
- if (!drv->probe_from) {
- wpa_printf(MSG_DEBUG, "%s: probe_from not set", __func__);
- return -1;
- }
-
- pos = resp;
- end = resp + sizeof(resp);
-
- mgmt = wpabuf_head(buf);
-
- /* reply: SCANRESP BSSID SSID IEs */
- ret = os_snprintf(pos, end - pos, "SCANRESP " MACSTR " ",
- MAC2STR(mgmt->bssid));
- if (ret < 0 || ret >= end - pos)
- return -1;
- pos += ret;
-
- ie = mgmt->u.probe_resp.variable;
- ie_end = wpabuf_head_u8(buf) + wpabuf_len(buf);
- if (ie_end - ie < 2 || ie[0] != WLAN_EID_SSID ||
- ie + 2 + ie[1] > ie_end)
- return -1;
- pos += wpa_snprintf_hex(pos, end - pos, ie + 2, ie[1]);
-
- ret = os_snprintf(pos, end - pos, " ");
- if (ret < 0 || ret >= end - pos)
- return -1;
- pos += ret;
- pos += wpa_snprintf_hex(pos, end - pos, ie, ie_end - ie);
-
- sendto(drv->test_socket, resp, pos - resp, 0,
- drv->probe_from, drv->probe_from_len);
-
- return 0;
-}
-
-
-static void test_sd_request(void *ctx, int freq, const u8 *sa, u8 dialog_token,
- u16 update_indic, const u8 *tlvs, size_t tlvs_len)
-{
- wpa_printf(MSG_DEBUG, "%s", __func__);
- /* TODO */
-}
-
-
-static void test_sd_response(void *ctx, const u8 *sa, u16 update_indic,
- const u8 *tlvs, size_t tlvs_len)
-{
- wpa_printf(MSG_DEBUG, "%s", __func__);
- /* TODO */
-}
-
-
-static void test_prov_disc_req(void *ctx, const u8 *peer, u16 config_methods,
- const u8 *dev_addr, const u8 *pri_dev_type,
- const char *dev_name, u16 supp_config_methods,
- u8 dev_capab, u8 group_capab,
- const u8 *group_id, size_t group_id_len)
-{
- wpa_printf(MSG_DEBUG, "%s(peer=" MACSTR " config_methods=0x%x)",
- __func__, MAC2STR(peer), config_methods);
- /* TODO */
-}
-
-
-static void test_prov_disc_resp(void *ctx, const u8 *peer, u16 config_methods)
-{
- wpa_printf(MSG_DEBUG, "%s(peer=" MACSTR " config_methods=0x%x)",
- __func__, MAC2STR(peer), config_methods);
- /* TODO */
-}
-
-
-static void test_p2p_debug_print(void *ctx, int level, const char *msg)
-{
- wpa_printf(level, "P2P: %s", msg);
-}
-
-#endif /* CONFIG_P2P */
-
-
-static int wpa_driver_test_init_p2p(struct wpa_driver_test_data *drv)
-{
-#ifdef CONFIG_P2P
- struct p2p_config p2p;
- unsigned int r;
- int i;
-
- os_memset(&p2p, 0, sizeof(p2p));
- p2p.cb_ctx = drv;
- p2p.debug_print = test_p2p_debug_print;
- p2p.p2p_scan = test_p2p_scan;
- p2p.send_action = test_send_action;
- p2p.send_action_done = test_send_action_done;
- p2p.go_neg_completed = test_go_neg_completed;
- p2p.go_neg_req_rx = test_go_neg_req_rx;
- p2p.dev_found = test_dev_found;
- p2p.start_listen = test_start_listen;
- p2p.stop_listen = test_stop_listen;
- p2p.send_probe_resp = test_send_probe_resp;
- p2p.sd_request = test_sd_request;
- p2p.sd_response = test_sd_response;
- p2p.prov_disc_req = test_prov_disc_req;
- p2p.prov_disc_resp = test_prov_disc_resp;
-
- os_memcpy(p2p.dev_addr, drv->own_addr, ETH_ALEN);
-
- p2p.reg_class = 12; /* TODO: change depending on location */
- /*
- * Pick one of the social channels randomly as the listen
- * channel.
- */
- os_get_random((u8 *) &r, sizeof(r));
- p2p.channel = 1 + (r % 3) * 5;
-
- /* TODO: change depending on location */
- p2p.op_reg_class = 12;
- /*
- * For initial tests, pick the operation channel randomly.
- * TODO: Use scan results (etc.) to select the best channel.
- */
- p2p.op_channel = 1 + r % 11;
-
- os_memcpy(p2p.country, "US ", 3);
-
- /* FIX: fetch available channels from the driver */
- p2p.channels.reg_classes = 1;
- p2p.channels.reg_class[0].reg_class = 12; /* US/12 = 2.4 GHz band */
- p2p.channels.reg_class[0].channels = 11;
- for (i = 0; i < 11; i++)
- p2p.channels.reg_class[0].channel[i] = i + 1;
-
- p2p.max_peers = 100;
-
- drv->p2p = p2p_init(&p2p);
- if (drv->p2p == NULL)
- return -1;
- return 0;
-#else /* CONFIG_P2P */
- wpa_printf(MSG_INFO, "driver_test: P2P support not included");
- return -1;
-#endif /* CONFIG_P2P */
-}
-
-
const struct wpa_driver_ops wpa_driver_test_ops = {
"test",
"wpa_supplicant test driver",
@@ -3309,14 +2675,4 @@
.remain_on_channel = wpa_driver_test_remain_on_channel,
.cancel_remain_on_channel = wpa_driver_test_cancel_remain_on_channel,
.probe_req_report = wpa_driver_test_probe_req_report,
-#ifdef CONFIG_P2P
- .p2p_find = wpa_driver_test_p2p_find,
- .p2p_stop_find = wpa_driver_test_p2p_stop_find,
- .p2p_listen = wpa_driver_test_p2p_listen,
- .p2p_connect = wpa_driver_test_p2p_connect,
- .wps_success_cb = wpa_driver_test_wps_success_cb,
- .p2p_group_formation_failed =
- wpa_driver_test_p2p_group_formation_failed,
- .p2p_set_params = wpa_driver_test_p2p_set_params,
-#endif /* CONFIG_P2P */
};
diff --git a/src/drivers/driver_wext.c b/src/drivers/driver_wext.c
index 6e2e771..e5734bd 100644
--- a/src/drivers/driver_wext.c
+++ b/src/drivers/driver_wext.c
@@ -31,10 +31,6 @@
#include "driver.h"
#include "driver_wext.h"
-#ifdef ANDROID
-#include "android_drv.h"
-#endif /* ANDROID */
-
static int wpa_driver_wext_flush_pmkid(void *priv);
static int wpa_driver_wext_get_range(void *priv);
static int wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv);
@@ -299,14 +295,6 @@
}
wpa_supplicant_event(ctx, EVENT_STKSTART, &data);
#endif /* CONFIG_PEERKEY */
-#ifdef ANDROID
- } else if (os_strncmp(custom, "STOP", 4) == 0) {
- wpa_msg(ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
- } else if (os_strncmp(custom, "START", 5) == 0) {
- wpa_msg(ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
- } else if (os_strncmp(custom, "HANG", 4) == 0) {
- wpa_msg(ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
-#endif /* ANDROID */
}
}
@@ -858,12 +846,6 @@
drv->mlme_sock = -1;
-#ifdef ANDROID
- drv->errors = 0;
- drv->driver_is_started = TRUE;
- drv->bgscan_enabled = 0;
-#endif /* ANDROID */
-
if (wpa_driver_wext_finish_drv_init(drv) < 0)
goto err3;
@@ -1869,10 +1851,8 @@
{
struct iwreq iwr;
const u8 null_bssid[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
-#ifndef ANDROID
u8 ssid[32];
int i;
-#endif /* ANDROID */
/*
* Only force-disconnect when the card is in infrastructure mode,
@@ -1893,7 +1873,6 @@
"selection on disconnect");
}
-#ifndef ANDROID
if (drv->cfg80211) {
/*
* cfg80211 supports SIOCSIWMLME commands, so there is
@@ -1919,7 +1898,6 @@
wpa_printf(MSG_DEBUG, "WEXT: Failed to set bogus "
"SSID to disconnect");
}
-#endif /* ANDROID */
}
}
@@ -1960,15 +1938,15 @@
int wpa_driver_wext_cipher2wext(int cipher)
{
switch (cipher) {
- case CIPHER_NONE:
+ case WPA_CIPHER_NONE:
return IW_AUTH_CIPHER_NONE;
- case CIPHER_WEP40:
+ case WPA_CIPHER_WEP40:
return IW_AUTH_CIPHER_WEP40;
- case CIPHER_TKIP:
+ case WPA_CIPHER_TKIP:
return IW_AUTH_CIPHER_TKIP;
- case CIPHER_CCMP:
+ case WPA_CIPHER_CCMP:
return IW_AUTH_CIPHER_CCMP;
- case CIPHER_WEP104:
+ case WPA_CIPHER_WEP104:
return IW_AUTH_CIPHER_WEP104;
default:
return 0;
@@ -1979,10 +1957,10 @@
int wpa_driver_wext_keymgmt2wext(int keymgmt)
{
switch (keymgmt) {
- case KEY_MGMT_802_1X:
- case KEY_MGMT_802_1X_NO_WPA:
+ case WPA_KEY_MGMT_IEEE8021X:
+ case WPA_KEY_MGMT_IEEE8021X_NO_WPA:
return IW_AUTH_KEY_MGMT_802_1X;
- case KEY_MGMT_PSK:
+ case WPA_KEY_MGMT_PSK:
return IW_AUTH_KEY_MGMT_PSK;
default:
return 0;
@@ -2099,9 +2077,9 @@
if (wpa_driver_wext_set_auth_param(drv,
IW_AUTH_KEY_MGMT, value) < 0)
ret = -1;
- value = params->key_mgmt_suite != KEY_MGMT_NONE ||
- params->pairwise_suite != CIPHER_NONE ||
- params->group_suite != CIPHER_NONE ||
+ value = params->key_mgmt_suite != WPA_KEY_MGMT_NONE ||
+ params->pairwise_suite != WPA_CIPHER_NONE ||
+ params->group_suite != WPA_CIPHER_NONE ||
params->wpa_ie_len;
if (wpa_driver_wext_set_auth_param(drv,
IW_AUTH_PRIVACY_INVOKED, value) < 0)
@@ -2110,8 +2088,8 @@
/* Allow unencrypted EAPOL messages even if pairwise keys are set when
* not using WPA. IEEE 802.1X specifies that these frames are not
* encrypted, but WPA encrypts them when pairwise keys are in use. */
- if (params->key_mgmt_suite == KEY_MGMT_802_1X ||
- params->key_mgmt_suite == KEY_MGMT_PSK)
+ if (params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
+ params->key_mgmt_suite == WPA_KEY_MGMT_PSK)
allow_unencrypted_eapol = 0;
else
allow_unencrypted_eapol = 1;
@@ -2338,129 +2316,6 @@
}
-#ifdef ANDROID
-
-static int android_wext_cmd(struct wpa_driver_wext_data *drv, const char *cmd)
-{
- struct iwreq iwr;
- char buf[MAX_DRV_CMD_SIZE];
- int ret;
-
- os_memset(&iwr, 0, sizeof(iwr));
- os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
-
- os_memset(buf, 0, sizeof(buf));
- os_strlcpy(buf, cmd, sizeof(buf));
-
- iwr.u.data.pointer = buf;
- iwr.u.data.length = sizeof(buf);
-
- ret = ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr);
-
- if (ret < 0) {
- wpa_printf(MSG_ERROR, "%s failed (%d): %s", __func__, ret,
- cmd);
- drv->errors++;
- if (drv->errors > DRV_NUMBER_SEQUENTIAL_ERRORS) {
- drv->errors = 0;
- wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE
- "HANGED");
- }
- return ret;
- }
-
- drv->errors = 0;
- return 0;
-}
-
-
-static int wext_sched_scan(void *priv, struct wpa_driver_scan_params *params,
- u32 interval)
-{
- struct wpa_driver_wext_data *drv = priv;
- struct iwreq iwr;
- int ret = 0, i = 0, bp;
- char buf[WEXT_PNO_MAX_COMMAND_SIZE];
-
- bp = WEXT_PNOSETUP_HEADER_SIZE;
- os_memcpy(buf, WEXT_PNOSETUP_HEADER, bp);
- buf[bp++] = WEXT_PNO_TLV_PREFIX;
- buf[bp++] = WEXT_PNO_TLV_VERSION;
- buf[bp++] = WEXT_PNO_TLV_SUBVERSION;
- buf[bp++] = WEXT_PNO_TLV_RESERVED;
-
- while (i < WEXT_PNO_AMOUNT && (size_t) i < params->num_ssids) {
- /*
- * Check that there is enough space needed for 1 more SSID, the
- * other sections and null termination.
- */
- if ((bp + WEXT_PNO_SSID_HEADER_SIZE + IW_ESSID_MAX_SIZE +
- WEXT_PNO_NONSSID_SECTIONS_SIZE + 1) >= (int) sizeof(buf))
- break;
-
- wpa_hexdump_ascii(MSG_DEBUG, "For PNO Scan",
- params->ssids[i].ssid,
- params->ssids[i].ssid_len);
- buf[bp++] = WEXT_PNO_SSID_SECTION;
- buf[bp++] = params->ssids[i].ssid_len;
- os_memcpy(&buf[bp], params->ssids[i].ssid,
- params->ssids[i].ssid_len);
- bp += params->ssids[i].ssid_len;
- i++;
- }
-
- buf[bp++] = WEXT_PNO_SCAN_INTERVAL_SECTION;
- /* TODO: consider using interval parameter (interval in msec) instead
- * of hardcoded value here */
- os_snprintf(&buf[bp], WEXT_PNO_SCAN_INTERVAL_LENGTH + 1, "%x",
- WEXT_PNO_SCAN_INTERVAL);
- bp += WEXT_PNO_SCAN_INTERVAL_LENGTH;
-
- buf[bp++] = WEXT_PNO_REPEAT_SECTION;
- os_snprintf(&buf[bp], WEXT_PNO_REPEAT_LENGTH + 1, "%x",
- WEXT_PNO_REPEAT);
- bp += WEXT_PNO_REPEAT_LENGTH;
-
- buf[bp++] = WEXT_PNO_MAX_REPEAT_SECTION;
- os_snprintf(&buf[bp], WEXT_PNO_MAX_REPEAT_LENGTH + 1, "%x",
- WEXT_PNO_MAX_REPEAT);
- bp += WEXT_PNO_MAX_REPEAT_LENGTH + 1;
-
- os_memset(&iwr, 0, sizeof(iwr));
- os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
- iwr.u.data.pointer = buf;
- iwr.u.data.length = bp;
-
- ret = ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr);
- if (ret < 0) {
- wpa_printf(MSG_ERROR, "ioctl[SIOCSIWPRIV] (pnosetup): %d",
- ret);
- drv->errors++;
- if (drv->errors > DRV_NUMBER_SEQUENTIAL_ERRORS) {
- drv->errors = 0;
- wpa_msg(drv->ctx, MSG_INFO,
- WPA_EVENT_DRIVER_STATE "HANGED");
- }
- return ret;
- }
-
- drv->errors = 0;
- drv->bgscan_enabled = 1;
-
- return android_wext_cmd(drv, "PNOFORCE 1");
-}
-
-
-static int wext_stop_sched_scan(void *priv)
-{
- struct wpa_driver_wext_data *drv = priv;
- drv->bgscan_enabled = 0;
- return android_wext_cmd(drv, "PNOFORCE 0");
-}
-
-#endif /* ANDROID */
-
-
const struct wpa_driver_ops wpa_driver_wext_ops = {
.name = "wext",
.desc = "Linux wireless extensions (generic)",
@@ -2480,8 +2335,4 @@
.get_capa = wpa_driver_wext_get_capa,
.set_operstate = wpa_driver_wext_set_operstate,
.get_radio_name = wext_get_radio_name,
-#ifdef ANDROID
- .sched_scan = wext_sched_scan,
- .stop_sched_scan = wext_stop_sched_scan,
-#endif /* ANDROID */
};
diff --git a/src/drivers/driver_wext.h b/src/drivers/driver_wext.h
index c4a5bc9..b4b5960 100644
--- a/src/drivers/driver_wext.h
+++ b/src/drivers/driver_wext.h
@@ -44,12 +44,6 @@
int cfg80211; /* whether driver is using cfg80211 */
u8 max_level;
-
-#ifdef ANDROID
- int errors;
- int driver_is_started;
- int bgscan_enabled;
-#endif /* ANDROID */
};
int wpa_driver_wext_get_bssid(void *priv, u8 *bssid);
diff --git a/src/drivers/drivers.c b/src/drivers/drivers.c
index 04eb4fd..446ab63 100644
--- a/src/drivers/drivers.c
+++ b/src/drivers/drivers.c
@@ -6,8 +6,9 @@
* See README for more details.
*/
-#include "includes.h"
-
+#include "utils/includes.h"
+#include "utils/common.h"
+#include "driver.h"
#ifdef CONFIG_DRIVER_WEXT
extern struct wpa_driver_ops wpa_driver_wext_ops; /* driver_wext.c */
diff --git a/src/drivers/netlink.c b/src/drivers/netlink.c
index 6c60550..2fa20b1 100644
--- a/src/drivers/netlink.c
+++ b/src/drivers/netlink.c
@@ -1,6 +1,6 @@
/*
* Netlink helper functions for driver wrappers
- * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -137,6 +137,35 @@
os_free(netlink);
}
+
+static const char * linkmode_str(int mode)
+{
+ switch (mode) {
+ case -1:
+ return "no change";
+ case 0:
+ return "kernel-control";
+ case 1:
+ return "userspace-control";
+ }
+ return "?";
+}
+
+
+static const char * operstate_str(int state)
+{
+ switch (state) {
+ case -1:
+ return "no change";
+ case IF_OPER_DORMANT:
+ return "IF_OPER_DORMANT";
+ case IF_OPER_UP:
+ return "IF_OPER_UP";
+ }
+ return "?";
+}
+
+
int netlink_send_oper_ifla(struct netlink_data *netlink, int ifindex,
int linkmode, int operstate)
{
@@ -184,8 +213,9 @@
RTA_LENGTH(sizeof(char));
}
- wpa_printf(MSG_DEBUG, "netlink: Operstate: linkmode=%d, operstate=%d",
- linkmode, operstate);
+ wpa_printf(MSG_DEBUG, "netlink: Operstate: ifindex=%d linkmode=%d (%s), operstate=%d (%s)",
+ ifindex, linkmode, linkmode_str(linkmode),
+ operstate, operstate_str(operstate));
ret = send(netlink->sock, &req, req.hdr.nlmsg_len, 0);
if (ret < 0) {
diff --git a/src/drivers/nl80211_copy.h b/src/drivers/nl80211_copy.h
index f752e98..91054fd 100644
--- a/src/drivers/nl80211_copy.h
+++ b/src/drivers/nl80211_copy.h
@@ -581,7 +581,14 @@
* operation, %NL80211_ATTR_MAC contains the peer MAC address, and
* %NL80211_ATTR_REASON_CODE the reason code to be used (only with
* %NL80211_TDLS_TEARDOWN).
- * @NL80211_CMD_TDLS_MGMT: Send a TDLS management frame.
+ * @NL80211_CMD_TDLS_MGMT: Send a TDLS management frame. The
+ * %NL80211_ATTR_TDLS_ACTION attribute determines the type of frame to be
+ * sent. Public Action codes (802.11-2012 8.1.5.1) will be sent as
+ * 802.11 management frames, while TDLS action codes (802.11-2012
+ * 8.5.13.1) will be encapsulated and sent as data frames. The currently
+ * supported Public Action code is %WLAN_PUB_ACTION_TDLS_DISCOVER_RES
+ * and the currently supported TDLS actions codes are given in
+ * &enum ieee80211_tdls_actioncode.
*
* @NL80211_CMD_UNEXPECTED_FRAME: Used by an application controlling an AP
* (or GO) interface (i.e. hostapd) to ask for unexpected frames to
@@ -686,6 +693,21 @@
* other station that transmission must be blocked until the channel
* switch is complete.
*
+ * @NL80211_CMD_VENDOR: Vendor-specified command/event. The command is specified
+ * by the %NL80211_ATTR_VENDOR_ID attribute and a sub-command in
+ * %NL80211_ATTR_VENDOR_SUBCMD. Parameter(s) can be transported in
+ * %NL80211_ATTR_VENDOR_DATA.
+ * For feature advertisement, the %NL80211_ATTR_VENDOR_DATA attribute is
+ * used in the wiphy data as a nested attribute containing descriptions
+ * (&struct nl80211_vendor_cmd_info) of the supported vendor commands.
+ * This may also be sent as an event with the same attributes.
+ *
+ * @NL80211_CMD_SET_QOS_MAP: Set Interworking QoS mapping for IP DSCP values.
+ * The QoS mapping information is included in %NL80211_ATTR_QOS_MAP. If
+ * that attribute is not included, QoS mapping is disabled. Since this
+ * QoS mapping is relevant for IP packets, it is only valid during an
+ * association. This is cleared on disassociation and AP restart.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -853,6 +875,10 @@
NL80211_CMD_CHANNEL_SWITCH,
+ NL80211_CMD_VENDOR,
+
+ NL80211_CMD_SET_QOS_MAP,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
@@ -1508,6 +1534,27 @@
* to react to radar events, e.g. initiate a channel switch or leave the
* IBSS network.
*
+ * @NL80211_ATTR_SUPPORT_5_MHZ: A flag indicating that the device supports
+ * 5 MHz channel bandwidth.
+ * @NL80211_ATTR_SUPPORT_10_MHZ: A flag indicating that the device supports
+ * 10 MHz channel bandwidth.
+ *
+ * @NL80211_ATTR_OPMODE_NOTIF: Operating mode field from Operating Mode
+ * Notification Element based on association request when used with
+ * %NL80211_CMD_NEW_STATION; u8 attribute.
+ *
+ * @NL80211_ATTR_VENDOR_ID: The vendor ID, either a 24-bit OUI or, if
+ * %NL80211_VENDOR_ID_IS_LINUX is set, a special Linux ID (not used yet)
+ * @NL80211_ATTR_VENDOR_SUBCMD: vendor sub-command
+ * @NL80211_ATTR_VENDOR_DATA: data for the vendor command, if any; this
+ * attribute is also used for vendor command feature advertisement
+ * @NL80211_ATTR_VENDOR_EVENTS: used for event list advertising in the wiphy
+ * info, containing a nested array of possible events
+ *
+ * @NL80211_ATTR_QOS_MAP: IP DSCP mapping for Interworking QoS mapping. This
+ * data is in the format defined for the payload of the QoS Map Set element
+ * in IEEE Std 802.11-2012, 8.4.2.97.
+ *
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -1824,6 +1871,18 @@
NL80211_ATTR_HANDLE_DFS,
+ NL80211_ATTR_SUPPORT_5_MHZ,
+ NL80211_ATTR_SUPPORT_10_MHZ,
+
+ NL80211_ATTR_OPMODE_NOTIF,
+
+ NL80211_ATTR_VENDOR_ID,
+ NL80211_ATTR_VENDOR_SUBCMD,
+ NL80211_ATTR_VENDOR_DATA,
+ NL80211_ATTR_VENDOR_EVENTS,
+
+ NL80211_ATTR_QOS_MAP,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -2224,10 +2283,9 @@
* @NL80211_FREQUENCY_ATTR_FREQ: Frequency in MHz
* @NL80211_FREQUENCY_ATTR_DISABLED: Channel is disabled in current
* regulatory domain.
- * @NL80211_FREQUENCY_ATTR_PASSIVE_SCAN: Only passive scanning is
- * permitted on this channel in current regulatory domain.
- * @NL80211_FREQUENCY_ATTR_NO_IBSS: IBSS networks are not permitted
- * on this channel in current regulatory domain.
+ * @NL80211_FREQUENCY_ATTR_NO_IR: no mechanisms that initiate radiation
+ * are permitted on this channel, this includes sending probe
+ * requests, or modes of operation that require beaconing.
* @NL80211_FREQUENCY_ATTR_RADAR: Radar detection is mandatory
* on this channel in current regulatory domain.
* @NL80211_FREQUENCY_ATTR_MAX_TX_POWER: Maximum transmission power in mBm
@@ -2254,8 +2312,8 @@
__NL80211_FREQUENCY_ATTR_INVALID,
NL80211_FREQUENCY_ATTR_FREQ,
NL80211_FREQUENCY_ATTR_DISABLED,
- NL80211_FREQUENCY_ATTR_PASSIVE_SCAN,
- NL80211_FREQUENCY_ATTR_NO_IBSS,
+ NL80211_FREQUENCY_ATTR_NO_IR,
+ __NL80211_FREQUENCY_ATTR_NO_IBSS,
NL80211_FREQUENCY_ATTR_RADAR,
NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
NL80211_FREQUENCY_ATTR_DFS_STATE,
@@ -2271,6 +2329,9 @@
};
#define NL80211_FREQUENCY_ATTR_MAX_TX_POWER NL80211_FREQUENCY_ATTR_MAX_TX_POWER
+#define NL80211_FREQUENCY_ATTR_PASSIVE_SCAN NL80211_FREQUENCY_ATTR_NO_IR
+#define NL80211_FREQUENCY_ATTR_NO_IBSS NL80211_FREQUENCY_ATTR_NO_IR
+#define NL80211_FREQUENCY_ATTR_NO_IR NL80211_FREQUENCY_ATTR_NO_IR
/**
* enum nl80211_bitrate_attr - bitrate attributes
@@ -2413,8 +2474,9 @@
* @NL80211_RRF_DFS: DFS support is required to be used
* @NL80211_RRF_PTP_ONLY: this is only for Point To Point links
* @NL80211_RRF_PTMP_ONLY: this is only for Point To Multi Point links
- * @NL80211_RRF_PASSIVE_SCAN: passive scan is required
- * @NL80211_RRF_NO_IBSS: no IBSS is allowed
+ * @NL80211_RRF_NO_IR: no mechanisms that initiate radiation are allowed,
+ * this includes probe requests or modes of operation that require
+ * beaconing.
*/
enum nl80211_reg_rule_flags {
NL80211_RRF_NO_OFDM = 1<<0,
@@ -2424,10 +2486,17 @@
NL80211_RRF_DFS = 1<<4,
NL80211_RRF_PTP_ONLY = 1<<5,
NL80211_RRF_PTMP_ONLY = 1<<6,
- NL80211_RRF_PASSIVE_SCAN = 1<<7,
- NL80211_RRF_NO_IBSS = 1<<8,
+ NL80211_RRF_NO_IR = 1<<7,
+ __NL80211_RRF_NO_IBSS = 1<<8,
};
+#define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR
+#define NL80211_RRF_NO_IBSS NL80211_RRF_NO_IR
+#define NL80211_RRF_NO_IR NL80211_RRF_NO_IR
+
+/* For backport compatibility with older userspace */
+#define NL80211_RRF_NO_IR_ALL (NL80211_RRF_NO_IR | __NL80211_RRF_NO_IBSS)
+
/**
* enum nl80211_dfs_regions - regulatory DFS regions
*
@@ -3058,21 +3127,35 @@
* in an array of rates as defined in IEEE 802.11 7.3.2.2 (u8 values with
* 1 = 500 kbps) but without the IE length restriction (at most
* %NL80211_MAX_SUPP_RATES in a single array).
- * @NL80211_TXRATE_MCS: HT (MCS) rates allowed for TX rate selection
+ * @NL80211_TXRATE_HT: HT (MCS) rates allowed for TX rate selection
* in an array of MCS numbers.
+ * @NL80211_TXRATE_VHT: VHT rates allowed for TX rate selection,
+ * see &struct nl80211_txrate_vht
* @__NL80211_TXRATE_AFTER_LAST: internal
* @NL80211_TXRATE_MAX: highest TX rate attribute
*/
enum nl80211_tx_rate_attributes {
__NL80211_TXRATE_INVALID,
NL80211_TXRATE_LEGACY,
- NL80211_TXRATE_MCS,
+ NL80211_TXRATE_HT,
+ NL80211_TXRATE_VHT,
/* keep last */
__NL80211_TXRATE_AFTER_LAST,
NL80211_TXRATE_MAX = __NL80211_TXRATE_AFTER_LAST - 1
};
+#define NL80211_TXRATE_MCS NL80211_TXRATE_HT
+#define NL80211_VHT_NSS_MAX 8
+
+/**
+ * struct nl80211_txrate_vht - VHT MCS/NSS txrate bitmap
+ * @mcs: MCS bitmap table for each NSS (array index 0 for 1 stream, etc.)
+ */
+struct nl80211_txrate_vht {
+ __u16 mcs[NL80211_VHT_NSS_MAX];
+};
+
/**
* enum nl80211_band - Frequency band
* @NL80211_BAND_2GHZ: 2.4 GHz ISM band
@@ -3934,4 +4017,24 @@
NL80211_RXMGMT_FLAG_ANSWERED = 1 << 0,
};
+/*
+ * If this flag is unset, the lower 24 bits are an OUI, if set
+ * a Linux nl80211 vendor ID is used (no such IDs are allocated
+ * yet, so that's not valid so far)
+ */
+#define NL80211_VENDOR_ID_IS_LINUX 0x80000000
+
+/**
+ * struct nl80211_vendor_cmd_info - vendor command data
+ * @vendor_id: If the %NL80211_VENDOR_ID_IS_LINUX flag is clear, then the
+ * value is a 24-bit OUI; if it is set then a separately allocated ID
+ * may be used, but no such IDs are allocated yet. New IDs should be
+ * added to this file when needed.
+ * @subcmd: sub-command ID for the command
+ */
+struct nl80211_vendor_cmd_info {
+ __u32 vendor_id;
+ __u32 subcmd;
+};
+
#endif /* __LINUX_NL80211_H */
diff --git a/src/drivers/priv_netlink.h b/src/drivers/priv_netlink.h
index 74d6ce5..6232088 100644
--- a/src/drivers/priv_netlink.h
+++ b/src/drivers/priv_netlink.h
@@ -69,6 +69,7 @@
(struct rtattr *) (((char *)(rta)) + RTA_ALIGN((rta)->rta_len)))
#define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len))
#define RTA_DATA(rta) ((void *) (((char *) (rta)) + RTA_LENGTH(0)))
+#define RTA_PAYLOAD(rta) ((int) ((rta)->rta_len) - RTA_LENGTH(0))
struct sockaddr_nl