1 // 2 // Copyright (C) 2012 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #ifndef SHILL_DEVICE_INFO_H_ 18 #define SHILL_DEVICE_INFO_H_ 19 20 #include <map> 21 #include <memory> 22 #include <set> 23 #include <string> 24 #include <vector> 25 26 #include <base/callback.h> 27 #include <base/cancelable_callback.h> 28 #include <base/files/file_path.h> 29 #include <base/memory/ref_counted.h> 30 #include <base/memory/weak_ptr.h> 31 #include <gtest/gtest_prod.h> // for FRIEND_TEST 32 33 #include "shill/device.h" 34 #include "shill/net/byte_string.h" 35 #include "shill/net/ip_address.h" 36 #include "shill/net/rtnl_listener.h" 37 #include "shill/net/shill_time.h" 38 #include "shill/technology.h" 39 40 namespace shill { 41 42 class Manager; 43 class Metrics; 44 class RoutingTable; 45 class RTNLHandler; 46 class RTNLMessage; 47 class Sockets; 48 49 #if !defined(DISABLE_WIFI) 50 class NetlinkManager; 51 class Nl80211Message; 52 #endif // DISABLE_WIFI 53 54 class DeviceInfo : public base::SupportsWeakPtr<DeviceInfo> { 55 public: 56 struct AddressData { AddressDataAddressData57 AddressData() 58 : address(IPAddress::kFamilyUnknown), flags(0), scope(0) {} AddressDataAddressData59 AddressData(const IPAddress& address_in, 60 unsigned char flags_in, 61 unsigned char scope_in) 62 : address(address_in), flags(flags_in), scope(scope_in) {} 63 IPAddress address; 64 unsigned char flags; 65 unsigned char scope; 66 }; 67 68 // Device name prefix for modem pseudo devices used in testing. 69 static const char kModemPseudoDeviceNamePrefix[]; 70 // Device name prefix for virtual ethernet devices used in testing. 71 static const char kEthernetPseudoDeviceNamePrefix[]; 72 // Device name prefix for virtual ethernet devices that should be ignored. 73 static const char kIgnoredDeviceNamePrefix[]; 74 // Time interval for polling for link statistics. 75 static const int kRequestLinkStatisticsIntervalMilliseconds; 76 77 DeviceInfo(ControlInterface* control_interface, 78 EventDispatcher* dispatcher, 79 Metrics* metrics, 80 Manager* manager); 81 virtual ~DeviceInfo(); 82 83 virtual void AddDeviceToBlackList(const std::string& device_name); 84 virtual void RemoveDeviceFromBlackList(const std::string& device_name); 85 virtual bool IsDeviceBlackListed(const std::string& device_name); 86 void Start(); 87 void Stop(); 88 89 std::vector<std::string> GetUninitializedTechnologies() const; 90 91 // Adds |device| to this DeviceInfo instance so that we can handle its link 92 // messages, and registers it with the manager. 93 virtual void RegisterDevice(const DeviceRefPtr& device); 94 95 // Remove |device| from this DeviceInfo. This function should only 96 // be called for cellular devices because the lifetime of the 97 // cellular devices is controlled by the Modem object and its 98 // communication to modem manager, rather than by RTNL messages. 99 virtual void DeregisterDevice(const DeviceRefPtr& device); 100 101 virtual DeviceRefPtr GetDevice(int interface_index) const; 102 virtual bool GetMACAddress(int interface_index, ByteString* address) const; 103 104 // Queries the kernel for a MAC address for |interface_index|. Returns an 105 // empty ByteString on failure. 106 virtual ByteString GetMACAddressFromKernel(int interface_index) const; 107 108 // Queries the kernel for the MAC address of |peer| on |interface_index|. 109 // Returns true and populates |mac_address| on success, otherwise returns 110 // false. 111 virtual bool GetMACAddressOfPeer(int interface_index, 112 const IPAddress& peer, 113 ByteString* mac_address) const; 114 115 virtual bool GetFlags(int interface_index, unsigned int* flags) const; 116 virtual bool GetByteCounts(int interface_index, 117 uint64_t* rx_bytes, uint64_t* tx_bytes) const; 118 virtual bool GetAddresses(int interface_index, 119 std::vector<AddressData>* addresses) const; 120 121 // Flush all addresses associated with |interface_index|. 122 virtual void FlushAddresses(int interface_index) const; 123 // Returns whether this interface does not have |this_address| 124 // but has another non-temporary address of the same family. 125 virtual bool HasOtherAddress( 126 int interface_index, const IPAddress& this_address) const; 127 128 // Get the preferred globally scoped IPv6 address for |interface_index|. 129 // This method returns true and sets |address| if a primary IPv6 address 130 // exists. Otherwise it returns false and leaves |address| unmodified. 131 virtual bool GetPrimaryIPv6Address(int interface_index, IPAddress* address); 132 133 // Get the IPv6 DNS server addresses for |interface_index|. This method 134 // returns true and sets |address_list| and |life_time_seconds| if the IPv6 135 // DNS server addresses exists. Otherwise, it returns false and leave 136 // |address_list| and |life_time_seconds| unmodified. |life_time_seconds| 137 // indicates the number of the seconds the DNS server is still valid for at 138 // the time of this function call. Value of 0 means the DNS server is not 139 // valid anymore, and value of 0xFFFFFFFF means the DNS server is valid 140 // forever. 141 virtual bool GetIPv6DnsServerAddresses(int interface_index, 142 std::vector<IPAddress>* address_list, 143 uint32_t* life_time_seconds); 144 145 // Returns true if any of the addresses on |interface_index| are on the 146 // same network prefix as |address|. 147 virtual bool HasDirectConnectivityTo( 148 int interface_index, const IPAddress& address) const; 149 150 virtual bool CreateTunnelInterface(std::string* interface_name) const; 151 virtual int OpenTunnelInterface(const std::string& interface_name) const; 152 virtual bool DeleteInterface(int interface_index) const; 153 154 // Returns the interface index for |interface_name| or -1 if unknown. 155 virtual int GetIndex(const std::string& interface_name) const; 156 157 // Sets the system hostname to |hostname|. 158 virtual bool SetHostname(const std::string& hostname) const; 159 160 private: 161 friend class DeviceInfoDelayedCreationTest; 162 friend class DeviceInfoTechnologyTest; 163 friend class DeviceInfoTest; 164 FRIEND_TEST(CellularTest, StartLinked); 165 FRIEND_TEST(DeviceInfoTest, CreateDeviceWiMax); 166 FRIEND_TEST(DeviceInfoTest, DeviceRemovedEvent); 167 FRIEND_TEST(DeviceInfoTest, GetUninitializedTechnologies); 168 FRIEND_TEST(DeviceInfoTest, HasSubdir); // For HasSubdir. 169 FRIEND_TEST(DeviceInfoTest, IPv6AddressChanged); // For infos_. 170 FRIEND_TEST(DeviceInfoTest, RequestLinkStatistics); 171 FRIEND_TEST(DeviceInfoTest, StartStop); 172 FRIEND_TEST(DeviceInfoTest, IPv6DnsServerAddressesChanged); // For infos_. 173 174 struct Info { InfoInfo175 Info() 176 : flags(0), 177 rx_bytes(0), 178 tx_bytes(0), 179 has_addresses_only(false), 180 technology(Technology::kUnknown) 181 {} 182 183 DeviceRefPtr device; 184 std::string name; 185 ByteString mac_address; 186 std::vector<AddressData> ip_addresses; 187 std::vector<IPAddress> ipv6_dns_server_addresses; 188 uint32_t ipv6_dns_server_lifetime_seconds; 189 time_t ipv6_dns_server_received_time_seconds; 190 unsigned int flags; 191 uint64_t rx_bytes; 192 uint64_t tx_bytes; 193 194 // This flag indicates that link information has not been retrieved yet; 195 // only the ip_addresses field is valid. 196 bool has_addresses_only; 197 198 Technology::Identifier technology; 199 }; 200 201 // Root of the kernel sysfs directory holding network device info. 202 static const char kDeviceInfoRoot[]; 203 // Name of the "cdc_ether" driver. This driver is not included in the 204 // kModemDrivers list because we need to do additional checking. 205 static const char kDriverCdcEther[]; 206 // Name of the "cdc_ncm" driver. This driver is not included in the 207 // kModemDrivers list because we need to do additional checking. 208 static const char kDriverCdcNcm[]; 209 // Name of the GDM WiMAX driver. 210 static const char kDriverGdmWiMax[]; 211 // Name of the virtio network driver. 212 static const char kDriverVirtioNet[]; 213 // Sysfs path to a device uevent file. 214 static const char kInterfaceUevent[]; 215 // Content of a device uevent file that indicates it is a wifi device. 216 static const char kInterfaceUeventWifiSignature[]; 217 // Sysfs path to a device via its interface name. 218 static const char kInterfaceDevice[]; 219 // Sysfs path to the driver of a device via its interface name. 220 static const char kInterfaceDriver[]; 221 // Sysfs path to the file that is used to determine if this is tun device. 222 static const char kInterfaceTunFlags[]; 223 // Sysfs path to the file that is used to determine if a wifi device is 224 // operating in monitor mode. 225 static const char kInterfaceType[]; 226 // Modem drivers that we support. 227 static const char* kModemDrivers[]; 228 // Path to the tun device. 229 static const char kTunDeviceName[]; 230 // Time to wait before registering devices which need extra time to detect. 231 static const int kDelayedDeviceCreationSeconds; 232 233 // Create a Device object for the interface named |linkname|, with a 234 // string-form MAC address |address|, whose kernel interface index 235 // is |interface_index| and detected technology is |technology|. 236 virtual DeviceRefPtr CreateDevice(const std::string& link_name, 237 const std::string& address, 238 int interface_index, 239 Technology::Identifier technology); 240 241 // Return the FilePath for a given |path_name| in the device sysinfo for 242 // a specific interface |iface_name|. 243 base::FilePath GetDeviceInfoPath(const std::string& iface_name, 244 const std::string& path_name); 245 // Return the contents of the device info file |path_name| for interface 246 // |iface_name| in output parameter |contents_out|. Returns true if file 247 // read succeeded, false otherwise. 248 bool GetDeviceInfoContents(const std::string& iface_name, 249 const std::string& path_name, 250 std::string* contents_out); 251 252 // Return the filepath for the target of the device info symbolic link 253 // |path_name| for interface |iface_name| in output parameter |path_out|. 254 // Returns true if symbolic link read succeeded, false otherwise. 255 bool GetDeviceInfoSymbolicLink(const std::string& iface_name, 256 const std::string& path_name, 257 base::FilePath* path_out); 258 // Classify the device named |iface_name|, and return an identifier 259 // indicating its type. 260 virtual Technology::Identifier GetDeviceTechnology( 261 const std::string& iface_name); 262 // Checks the device specified by |iface_name| to see if it's a modem device. 263 // This method assumes that |iface_name| has already been determined to be 264 // using the cdc_ether / cdc_ncm driver. 265 bool IsCdcEthernetModemDevice(const std::string& iface_name); 266 // Returns true if |base_dir| has a subdirectory named |subdir|. 267 // |subdir| can be an immediate subdirectory of |base_dir| or can be 268 // several levels deep. 269 static bool HasSubdir(const base::FilePath& base_dir, 270 const base::FilePath& subdir); 271 272 // Returns true and sets |link_name| to the interface name contained 273 // in |msg| if one is provided. Returns false otherwise. 274 bool GetLinkNameFromMessage(const RTNLMessage& msg, std::string* link_name); 275 276 // Returns true if |msg| pertains to a blacklisted device whose link name 277 // is now different from the name it was assigned before. 278 bool IsRenamedBlacklistedDevice(const RTNLMessage& msg); 279 280 void AddLinkMsgHandler(const RTNLMessage& msg); 281 void DelLinkMsgHandler(const RTNLMessage& msg); 282 void LinkMsgHandler(const RTNLMessage& msg); 283 void AddressMsgHandler(const RTNLMessage& msg); 284 void RdnssMsgHandler(const RTNLMessage& msg); 285 286 const Info* GetInfo(int interface_index) const; 287 void RemoveInfo(int interface_index); 288 void DelayDeviceCreation(int interface_index); 289 void DelayedDeviceCreationTask(); 290 void RetrieveLinkStatistics(int interface_index, const RTNLMessage& msg); 291 void RequestLinkStatistics(); 292 293 #if !defined(DISABLE_WIFI) 294 // Use nl80211 to get information on |interface_index|. 295 void GetWiFiInterfaceInfo(int interface_index); 296 void OnWiFiInterfaceInfoReceived(const Nl80211Message& message); 297 #endif // DISABLE_WIFI 298 set_sockets(Sockets * sockets)299 void set_sockets(Sockets* sockets) { sockets_.reset(sockets); } 300 301 ControlInterface* control_interface_; 302 EventDispatcher* dispatcher_; 303 Metrics* metrics_; 304 Manager* manager_; 305 306 std::map<int, Info> infos_; // Maps interface index to Info. 307 std::map<std::string, int> indices_; // Maps interface name to index. 308 309 base::Callback<void(const RTNLMessage&)> link_callback_; 310 base::Callback<void(const RTNLMessage&)> address_callback_; 311 base::Callback<void(const RTNLMessage&)> rdnss_callback_; 312 std::unique_ptr<RTNLListener> link_listener_; 313 std::unique_ptr<RTNLListener> address_listener_; 314 std::unique_ptr<RTNLListener> rdnss_listener_; 315 std::set<std::string> black_list_; 316 base::FilePath device_info_root_; 317 318 // Keep track of devices that require a delayed call to CreateDevice(). 319 base::CancelableClosure delayed_devices_callback_; 320 std::set<int> delayed_devices_; 321 322 // Maintain a callback for the periodic link statistics poll task. 323 base::CancelableClosure request_link_statistics_callback_; 324 325 // Cache copy of singleton pointers. 326 RoutingTable* routing_table_; 327 RTNLHandler* rtnl_handler_; 328 #if !defined(DISABLE_WIFI) 329 NetlinkManager* netlink_manager_; 330 #endif // DISABLE_WIFI 331 332 // A member of the class so that a mock can be injected for testing. 333 std::unique_ptr<Sockets> sockets_; 334 335 Time* time_; 336 337 DISALLOW_COPY_AND_ASSIGN(DeviceInfo); 338 }; 339 340 } // namespace shill 341 342 #endif // SHILL_DEVICE_INFO_H_ 343