// Copyright 2018 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/if.h>
#include <net/if_dl.h>
#include <net/if_media.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>

// net/if.h must be included before this.
#include <ifaddrs.h>

#include <algorithm>
#include <string>
#include <vector>

#include "platform/api/network_interface.h"
#include "platform/base/ip_address.h"
#include "platform/impl/network_interface.h"
#include "platform/impl/scoped_pipe.h"
#include "util/osp_logging.h"

namespace openscreen {

namespace {

// Assuming |netmask| consists of 0 to N*8 leftmost bits set followed by all
// unset bits, return the number of leftmost bits set. This also sanity-checks
// that there are no "holes" in the bit pattern, returning 0 if that check
// fails.
template <size_t N>
uint8_t ToPrefixLength(const uint8_t (&netmask)[N]) {
  uint8_t result = 0;
  size_t i = 0;

  // Ensure all of the leftmost bits are set.
  while (i < N && netmask[i] == UINT8_C(0xff)) {
    result += 8;
    ++i;
  }

  // Check the intermediate byte, the first that is not 0xFF,
  // e.g. 0b11100000 or 0x00
  if (i < N && netmask[i] != UINT8_C(0x00)) {
    uint8_t last_byte = netmask[i];
    // Check the left most bit, bitshifting as we go.
    while (last_byte & UINT8_C(0x80)) {
      ++result;
      last_byte <<= 1;
    }
    OSP_CHECK(last_byte == UINT8_C(0x00));
    ++i;
  }

  // Ensure the rest of the bytes are zeroed out.
  while (i < N) {
    OSP_CHECK(netmask[i] == UINT8_C(0x00));
    ++i;
  }

  return result;
}

std::vector<InterfaceInfo> ProcessInterfacesList(ifaddrs* interfaces) {
  // Socket used for querying interface media types.
  const ScopedFd ioctl_socket(socket(AF_INET6, SOCK_DGRAM, 0));

  // Walk the |interfaces| linked list, creating the hierarchical structure.
  std::vector<InterfaceInfo> results;
  for (ifaddrs* cur = interfaces; cur; cur = cur->ifa_next) {
    // Skip: 1) interfaces that are down, 2) interfaces with no address
    // configured.
    if (!(IFF_RUNNING & cur->ifa_flags) || !cur->ifa_addr) {
      continue;
    }

    // Look-up the InterfaceInfo entry by name. Auto-create a new one if none by
    // the current name exists in |results|.
    const std::string name = cur->ifa_name;
    const auto it = std::find_if(
        results.begin(), results.end(),
        [&name](const InterfaceInfo& info) { return info.name == name; });
    InterfaceInfo* interface;
    if (it == results.end()) {
      InterfaceInfo::Type type = InterfaceInfo::Type::kOther;
      // Query for the interface media type and status. If not valid/active,
      // skip further processing. Note that "active" here means the media is
      // connected to the interface, which is different than the interface being
      // up/down.
      ifmediareq ifmr;
      memset(&ifmr, 0, sizeof(ifmr));
      // Note: Because of the memset(), memcpy() can be used to copy the
      // ifmr.ifm_name string, and it will always be NUL terminated.
      memcpy(ifmr.ifm_name, name.data(),
             std::min(name.size(), sizeof(ifmr.ifm_name) - 1));
      if (ioctl(ioctl_socket.get(), SIOCGIFMEDIA, &ifmr) >= 0) {
        if (!((ifmr.ifm_status & IFM_AVALID) &&
              (ifmr.ifm_status & IFM_ACTIVE))) {
          continue;  // Skip this interface since it's not valid or active.
        }
        if (ifmr.ifm_current & IFM_IEEE80211) {
          type = InterfaceInfo::Type::kWifi;
        } else if (ifmr.ifm_current & IFM_ETHER) {
          type = InterfaceInfo::Type::kEthernet;
        }
      } else if (cur->ifa_flags & IFF_LOOPBACK) {
        type = InterfaceInfo::Type::kLoopback;
      } else {
        continue;
      }

      // Start with an unknown hardware ethernet address, which should be
      // updated as the linked list is walked.
      const uint8_t kUnknownHardwareAddress[6] = {0, 0, 0, 0, 0, 0};
      results.emplace_back(if_nametoindex(cur->ifa_name),
                           kUnknownHardwareAddress, name, type,
                           // IPSubnets to be filled-in later.
                           std::vector<IPSubnet>());
      interface = &(results.back());
    } else {
      interface = &(*it);
    }

    // Add another address to the list of addresses for the current interface.
    if (cur->ifa_addr->sa_family == AF_LINK) {  // Hardware ethernet address.
      auto* const addr_dl = reinterpret_cast<const sockaddr_dl*>(cur->ifa_addr);
      const caddr_t lladdr = LLADDR(addr_dl);
      static_assert(sizeof(lladdr) >= sizeof(interface->hardware_address),
                    "Platform defines too-small link addresses?");
      memcpy(&interface->hardware_address[0], &lladdr[0],
             sizeof(interface->hardware_address));
    } else if (cur->ifa_addr->sa_family == AF_INET6) {  // Ipv6 address.
      auto* const addr_in6 =
          reinterpret_cast<const sockaddr_in6*>(cur->ifa_addr);
      uint8_t tmp[sizeof(addr_in6->sin6_addr.s6_addr)];
      memcpy(tmp, &(addr_in6->sin6_addr.s6_addr), sizeof(tmp));
      const IPAddress ip(IPAddress::Version::kV6, tmp);
      memset(tmp, 0, sizeof(tmp));
      if (cur->ifa_netmask && cur->ifa_netmask->sa_family == AF_INET6) {
        memcpy(tmp,
               &(reinterpret_cast<const sockaddr_in6*>(cur->ifa_netmask)
                     ->sin6_addr.s6_addr),
               sizeof(tmp));
      }
      interface->addresses.emplace_back(ip, ToPrefixLength(tmp));
    } else if (cur->ifa_addr->sa_family == AF_INET) {  // Ipv4 address.
      auto* const addr_in = reinterpret_cast<const sockaddr_in*>(cur->ifa_addr);
      uint8_t tmp[sizeof(addr_in->sin_addr.s_addr)];
      memcpy(tmp, &(addr_in->sin_addr.s_addr), sizeof(tmp));
      IPAddress ip(IPAddress::Version::kV4, tmp);
      memset(tmp, 0, sizeof(tmp));
      if (cur->ifa_netmask && cur->ifa_netmask->sa_family == AF_INET) {
        memcpy(tmp,
               &(reinterpret_cast<const sockaddr_in*>(cur->ifa_netmask)
                     ->sin_addr.s_addr),
               sizeof(tmp));
      }
      interface->addresses.emplace_back(ip, ToPrefixLength(tmp));
    }
  }

  return results;
}

}  // namespace

std::vector<InterfaceInfo> GetAllInterfaces() {
  std::vector<InterfaceInfo> results;
  ifaddrs* interfaces;
  if (getifaddrs(&interfaces) == 0) {
    results = ProcessInterfacesList(interfaces);
    freeifaddrs(interfaces);
  }
  return results;
}

}  // namespace openscreen
