• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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