Index: net/base/address_tracker_linux.cc |
diff --git a/net/base/address_tracker_linux.cc b/net/base/address_tracker_linux.cc |
index 731bf4f97785ebf45837c35a4fe4033bd4ffffff..d94104da6294075287bc378d62b954873fb1ab74 100644 |
--- a/net/base/address_tracker_linux.cc |
+++ b/net/base/address_tracker_linux.cc |
@@ -6,6 +6,7 @@ |
#include <errno.h> |
#include <linux/if.h> |
+#include <linux/wireless.h> |
#include <sys/ioctl.h> |
#include "base/files/scoped_file.h" |
@@ -78,6 +79,22 @@ bool GetAddress(const struct nlmsghdr* header, |
return true; |
} |
+std::string GetInterfaceSSID(const std::string& ifname) { |
+ int ioctl_socket = socket(AF_INET, SOCK_DGRAM, 0); |
+ if (ioctl_socket < 0) |
+ return ""; |
+ struct iwreq wreq; |
+ memset(&wreq, 0, sizeof(wreq)); |
+ strncpy(wreq.ifr_name, ifname.c_str(), IFNAMSIZ - 1); |
+ |
+ char ssid[IW_ESSID_MAX_SIZE + 1] = {0}; |
+ wreq.u.essid.pointer = ssid; |
+ wreq.u.essid.length = IW_ESSID_MAX_SIZE; |
+ int rv = ioctl(ioctl_socket, SIOCGIWESSID, &wreq); |
+ close(ioctl_socket); |
+ return (rv == 0) ? ssid : ""; |
+} |
+ |
} // namespace |
// static |
@@ -95,6 +112,26 @@ char* AddressTrackerLinux::GetInterfaceName(int interface_index, char* buf) { |
return buf; |
} |
+// static |
+std::string AddressTrackerLinux::ConnectionSSIDFromInterfaceList( |
+ const NetworkInterfaceList& interfaces, |
+ GetInterfaceSSIDFunction get_interface_ssid) { |
+ std::string connected_ssid; |
+ bool first = true; |
+ for (size_t i = 0; i < interfaces.size(); ++i) { |
+ if (interfaces[i].type != NetworkChangeNotifier::CONNECTION_WIFI) |
+ return ""; |
+ std::string ssid = get_interface_ssid(interfaces[i].name); |
+ if (first) { |
+ first = false; |
+ connected_ssid = ssid; |
+ } else if (ssid != connected_ssid) { |
+ return ""; |
+ } |
+ } |
+ return connected_ssid; |
+} |
+ |
AddressTrackerLinux::AddressTrackerLinux() |
: get_interface_name_(GetInterfaceName), |
address_callback_(base::Bind(&base::DoNothing)), |
@@ -223,6 +260,7 @@ void AddressTrackerLinux::AbortAndForceOnline() { |
current_connection_type_ = NetworkChangeNotifier::CONNECTION_UNKNOWN; |
connection_type_initialized_ = true; |
connection_type_initialized_cv_.Signal(); |
+ current_wifi_ssid_ = ""; |
} |
AddressTrackerLinux::AddressMap AddressTrackerLinux::GetAddressMap() const { |
@@ -247,6 +285,12 @@ AddressTrackerLinux::GetCurrentConnectionType() { |
return current_connection_type_; |
} |
+std::string AddressTrackerLinux::GetCurrentWiFiSSID() { |
+ // Don't wait for initialization, return an empty SSID if not initialized. |
+ AddressTrackerAutoLock lock(*this, wifi_ssid_lock_); |
+ return current_wifi_ssid_; |
+} |
+ |
void AddressTrackerLinux::ReadMessages(bool* address_changed, |
bool* link_changed, |
bool* tunnel_changed) { |
@@ -275,7 +319,7 @@ void AddressTrackerLinux::ReadMessages(bool* address_changed, |
HandleMessage(buffer, rv, address_changed, link_changed, tunnel_changed); |
} |
if (*link_changed || *address_changed) |
- UpdateCurrentConnectionType(); |
+ UpdateCurrentConnectionTypeAndSSID(); |
} |
void AddressTrackerLinux::HandleMessage(char* buffer, |
@@ -395,7 +439,7 @@ bool AddressTrackerLinux::IsTunnelInterface(int interface_index) const { |
return strncmp(get_interface_name_(interface_index, buf), "tun", 3) == 0; |
} |
-void AddressTrackerLinux::UpdateCurrentConnectionType() { |
+void AddressTrackerLinux::UpdateCurrentConnectionTypeAndSSID() { |
AddressTrackerLinux::AddressMap address_map = GetAddressMap(); |
base::hash_set<int> online_links = GetOnlineLinks(); |
@@ -414,16 +458,24 @@ void AddressTrackerLinux::UpdateCurrentConnectionType() { |
NetworkInterfaceList networks; |
NetworkChangeNotifier::ConnectionType type = |
NetworkChangeNotifier::CONNECTION_NONE; |
+ std::string ssid; |
if (GetNetworkListImpl(&networks, 0, online_links, address_map, |
get_interface_name_)) { |
type = NetworkChangeNotifier::ConnectionTypeFromInterfaceList(networks); |
+ ssid = ConnectionSSIDFromInterfaceList(networks, GetInterfaceSSID); |
} else { |
type = online_links.empty() ? NetworkChangeNotifier::CONNECTION_NONE |
: NetworkChangeNotifier::CONNECTION_UNKNOWN; |
} |
- AddressTrackerAutoLock lock(*this, connection_type_lock_); |
- current_connection_type_ = type; |
+ { |
+ AddressTrackerAutoLock lock(*this, connection_type_lock_); |
+ current_connection_type_ = type; |
+ } |
+ { |
+ AddressTrackerAutoLock lock(*this, wifi_ssid_lock_); |
+ current_wifi_ssid_ = ssid; |
+ } |
} |
AddressTrackerLinux::AddressTrackerAutoLock::AddressTrackerAutoLock( |