// Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/base/network_interfaces_linux.h"

#include <memory>

#if !defined(OS_ANDROID)
#include <linux/ethtool.h>
#endif  // !defined(OS_ANDROID)
#include <linux/if.h>
#include <linux/sockios.h>
#include <linux/wireless.h>
#include <set>
#include <sys/ioctl.h>
#include <sys/types.h>

#include "base/files/file_path.h"
#include "base/files/scoped_file.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_tokenizer.h"
#include "base/strings/string_util.h"
#include "base/threading/thread_restrictions.h"
#include "net/base/address_tracker_linux.h"
#include "net/base/escape.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/base/network_interfaces_posix.h"
#include "url/gurl.h"

#if defined(OS_ANDROID)
#include "net/android/network_library.h"
#endif

namespace net {

namespace {

// When returning true, the platform native IPv6 address attributes were
// successfully converted to net IP address attributes. Otherwise, returning
// false and the caller should drop the IP address which can't be used by the
// application layer.
bool TryConvertNativeToNetIPAttributes(int native_attributes,
                                       int* net_attributes) {
  // For Linux/ChromeOS/Android, we disallow addresses with attributes
  // IFA_F_OPTIMISTIC, IFA_F_DADFAILED, and IFA_F_TENTATIVE as these
  // are still progressing through duplicated address detection (DAD)
  // and shouldn't be used by the application layer until DAD process
  // is completed.
  if (native_attributes & (
#if !defined(OS_ANDROID)
                              IFA_F_OPTIMISTIC | IFA_F_DADFAILED |
#endif  // !OS_ANDROID
                              IFA_F_TENTATIVE)) {
    return false;
  }

  if (native_attributes & IFA_F_TEMPORARY) {
    *net_attributes |= IP_ADDRESS_ATTRIBUTE_TEMPORARY;
  }

  if (native_attributes & IFA_F_DEPRECATED) {
    *net_attributes |= IP_ADDRESS_ATTRIBUTE_DEPRECATED;
  }

  return true;
}

}  // namespace

namespace internal {

// Gets the connection type for interface |ifname| by checking for wireless
// or ethtool extensions.
NetworkChangeNotifier::ConnectionType GetInterfaceConnectionType(
    const std::string& ifname) {
  base::ScopedFD s(socket(AF_INET, SOCK_STREAM, 0));
  if (!s.is_valid())
    return NetworkChangeNotifier::CONNECTION_UNKNOWN;

  // Test wireless extensions for CONNECTION_WIFI
  struct iwreq pwrq = {};
  strncpy(pwrq.ifr_name, ifname.c_str(), IFNAMSIZ - 1);
  if (ioctl(s.get(), SIOCGIWNAME, &pwrq) != -1)
    return NetworkChangeNotifier::CONNECTION_WIFI;

#if !defined(OS_ANDROID)
  // Test ethtool for CONNECTION_ETHERNET
  struct ethtool_cmd ecmd = {};
  ecmd.cmd = ETHTOOL_GSET;
  struct ifreq ifr = {};
  ifr.ifr_data = &ecmd;
  strncpy(ifr.ifr_name, ifname.c_str(), IFNAMSIZ - 1);
  if (ioctl(s.get(), SIOCETHTOOL, &ifr) != -1)
    return NetworkChangeNotifier::CONNECTION_ETHERNET;
#endif  // !defined(OS_ANDROID)

  return NetworkChangeNotifier::CONNECTION_UNKNOWN;
}

std::string GetInterfaceSSID(const std::string& ifname) {
  base::ScopedFD ioctl_socket(socket(AF_INET, SOCK_DGRAM, 0));
  if (!ioctl_socket.is_valid())
    return "";
  struct iwreq 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;
  if (ioctl(ioctl_socket.get(), SIOCGIWESSID, &wreq) != -1)
    return ssid;
  return "";
}

bool GetNetworkListImpl(
    NetworkInterfaceList* networks,
    int policy,
    const std::unordered_set<int>& online_links,
    const internal::AddressTrackerLinux::AddressMap& address_map,
    GetInterfaceNameFunction get_interface_name) {
  std::map<int, std::string> ifnames;

  for (internal::AddressTrackerLinux::AddressMap::const_iterator it =
           address_map.begin();
       it != address_map.end(); ++it) {
    // Ignore addresses whose links are not online.
    if (online_links.find(it->second.ifa_index) == online_links.end())
      continue;

    sockaddr_storage sock_addr;
    socklen_t sock_len = sizeof(sockaddr_storage);

    // Convert to sockaddr for next check.
    if (!IPEndPoint(it->first, 0)
             .ToSockAddr(reinterpret_cast<sockaddr*>(&sock_addr), &sock_len)) {
      continue;
    }

    // Skip unspecified addresses (i.e. made of zeroes) and loopback addresses
    if (IsLoopbackOrUnspecifiedAddress(reinterpret_cast<sockaddr*>(&sock_addr)))
      continue;

    int ip_attributes = IP_ADDRESS_ATTRIBUTE_NONE;

    if (it->second.ifa_family == AF_INET6) {
      // Ignore addresses whose attributes are not actionable by
      // the application layer.
      if (!TryConvertNativeToNetIPAttributes(it->second.ifa_flags,
                                             &ip_attributes))
        continue;
    }

    // Find the name of this link.
    std::map<int, std::string>::const_iterator itname =
        ifnames.find(it->second.ifa_index);
    std::string ifname;
    if (itname == ifnames.end()) {
      char buffer[IFNAMSIZ] = {0};
      ifname.assign(get_interface_name(it->second.ifa_index, buffer));
      // Ignore addresses whose interface name can't be retrieved.
      if (ifname.empty())
        continue;
      ifnames[it->second.ifa_index] = ifname;
    } else {
      ifname = itname->second;
    }

    // Based on the interface name and policy, determine whether we
    // should ignore it.
    if (ShouldIgnoreInterface(ifname, policy))
      continue;

    NetworkChangeNotifier::ConnectionType type =
        GetInterfaceConnectionType(ifname);

    networks->push_back(
        NetworkInterface(ifname, ifname, it->second.ifa_index, type, it->first,
                         it->second.ifa_prefixlen, ip_attributes));
  }

  return true;
}

std::string GetWifiSSIDFromInterfaceListInternal(
    const NetworkInterfaceList& interfaces,
    internal::GetInterfaceSSIDFunction get_interface_ssid) {
  std::string connected_ssid;
  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 (i == 0) {
      connected_ssid = ssid;
    } else if (ssid != connected_ssid) {
      return "";
    }
  }
  return connected_ssid;
}

}  // namespace internal

bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
  if (networks == NULL)
    return false;

  internal::AddressTrackerLinux tracker;
  tracker.Init();

  return internal::GetNetworkListImpl(
      networks, policy, tracker.GetOnlineLinks(), tracker.GetAddressMap(),
      &internal::AddressTrackerLinux::GetInterfaceName);
}

std::string GetWifiSSID() {
// On Android, obtain the SSID using the Android-specific APIs.
#if defined(OS_ANDROID)
  return android::GetWifiSSID();
#endif
  NetworkInterfaceList networks;
  if (GetNetworkList(&networks, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES)) {
    return internal::GetWifiSSIDFromInterfaceListInternal(
        networks, internal::GetInterfaceSSID);
  }
  return "";
}

}  // namespace net
