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
40namespace shill {
41
42class Manager;
43class Metrics;
44class RoutingTable;
45class RTNLHandler;
46class RTNLMessage;
47class Sockets;
48
49#if !defined(DISABLE_WIFI)
50class NetlinkManager;
51class Nl80211Message;
52#endif  // DISABLE_WIFI
53
54class DeviceInfo : public base::SupportsWeakPtr<DeviceInfo> {
55 public:
56  struct AddressData {
57    AddressData()
58        : address(IPAddress::kFamilyUnknown), flags(0), scope(0) {}
59    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 {
175    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
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