Home | History | Annotate | Download | only in shill
      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 {
     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