/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <gtest/gtest.h>

#include <ifaddrs.h>

#include <dirent.h>
#include <fcntl.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/ioctl.h>

// (glibc as of 2.37 has redefinitions if you include these before <net/if.h>.)
#include <linux/if.h>
#include <linux/if_packet.h>

#include <algorithm>
#include <map>
#include <thread>
#include <vector>

#include "utils.h"

TEST(ifaddrs, freeifaddrs_null) {
  freeifaddrs(nullptr);
}

// We can't statically say much about what network interfaces are available, but we can be pretty
// sure there's a loopback interface, and that it has IPv4, IPv6, and AF_PACKET entries.
TEST(ifaddrs, getifaddrs_lo) {
  ifaddrs* addrs = nullptr;

  ASSERT_EQ(0, getifaddrs(&addrs));
  ASSERT_TRUE(addrs != nullptr);

  ifaddrs* lo_inet4 = nullptr;
  ifaddrs* lo_inet6 = nullptr;
  ifaddrs* lo_packet = nullptr;
  for (ifaddrs* addr = addrs; addr != nullptr; addr = addr->ifa_next) {
    if (addr->ifa_name && strcmp(addr->ifa_name, "lo") == 0) {
      if (addr->ifa_addr && addr->ifa_addr->sa_family == AF_INET) lo_inet4 = addr;
      else if (addr->ifa_addr && addr->ifa_addr->sa_family == AF_INET6) lo_inet6 = addr;
      else if (addr->ifa_addr && addr->ifa_addr->sa_family == AF_PACKET) lo_packet = addr;
    }
  }

  // Does the IPv4 entry look right?
  ASSERT_TRUE(lo_inet4 != nullptr);
  const sockaddr_in* sa_inet4 = reinterpret_cast<const sockaddr_in*>(lo_inet4->ifa_addr);
  ASSERT_TRUE(ntohl(sa_inet4->sin_addr.s_addr) == INADDR_LOOPBACK);

  // Does the IPv6 entry look right?
  ASSERT_TRUE(lo_inet6 != nullptr);
  const sockaddr_in6* sa_inet6 = reinterpret_cast<const sockaddr_in6*>(lo_inet6->ifa_addr);
  ASSERT_TRUE(IN6_IS_ADDR_LOOPBACK(&sa_inet6->sin6_addr));

  // Does the AF_PACKET entry look right?
  ASSERT_TRUE(lo_packet != nullptr);
  const sockaddr_ll* sa_ll = reinterpret_cast<const sockaddr_ll*>(lo_packet->ifa_addr);
  ASSERT_EQ(6, sa_ll->sll_halen);

  freeifaddrs(addrs);
}

// Check that getifaddrs sees the same list of interfaces as /sys/class/net.
TEST(ifaddrs, getifaddrs_interfaces) {
  std::vector<std::string> ifaddrs_socks;
  {
    ifaddrs* addrs;
    ASSERT_EQ(0, getifaddrs(&addrs));

    for (ifaddrs* addr = addrs; addr != nullptr; addr = addr->ifa_next) {
      int family = addr->ifa_addr ? addr->ifa_addr->sa_family :
          addr->ifa_broadaddr ? addr->ifa_broadaddr->sa_family :
          AF_UNSPEC;

      if (family == AF_PACKET || family == AF_UNSPEC) {
        ifaddrs_socks.push_back(std::string(addr->ifa_name));
      }
    }

    freeifaddrs(addrs);
  }

  std::vector<std::string> sys_class_net;
  {
    std::unique_ptr<DIR, decltype(&closedir)> d(opendir("/sys/class/net"), closedir);
    ASSERT_TRUE(d != nullptr);
    dirent* dir;
    while ((dir = readdir(d.get())) != nullptr) {
      if (dir->d_type == DT_LNK) {
        sys_class_net.push_back(std::string(dir->d_name));
      }
    }
  }

  ASSERT_TRUE(std::is_permutation(ifaddrs_socks.begin(), ifaddrs_socks.end(),
                                  sys_class_net.begin()));
}

static void CheckAddressIsInSet(const std::string& if_name, bool unicast,
                                const std::set<in_addr_t>& addrs) {
  ifreq ifr;
  memset(&ifr, 0, sizeof(ifr));
  ifr.ifr_addr.sa_family = AF_INET;
  if_name.copy(ifr.ifr_name, IFNAMSIZ - 1);

  int fd = socket(AF_INET, SOCK_DGRAM, 0);
  ASSERT_TRUE(fd != -1);

  int request = SIOCGIFADDR;
  if (!unicast) {
    // For non-unicast, the specific ioctl to use depends on whether the IFF_BROADCAST flag is set.
    ASSERT_EQ(0, ioctl(fd, SIOCGIFFLAGS, &ifr)) << if_name << ' ' << strerror(errno);
    request = ((ifr.ifr_flags & IFF_BROADCAST) != 0) ? SIOCGIFBRDADDR : SIOCGIFDSTADDR;
  }

  ASSERT_EQ(0, ioctl(fd, request, &ifr)) << if_name << ' ' << strerror(errno);
  close(fd);

  sockaddr_in* sock = reinterpret_cast<sockaddr_in*>(&ifr.ifr_addr);
  in_addr_t addr = sock->sin_addr.s_addr;

  EXPECT_TRUE(addrs.find(addr) != addrs.end()) << if_name << ' ' << std::hex << ntohl(addr);
}

TEST(ifaddrs, getifaddrs_INET) {
  std::map<std::string, std::set<in_addr_t>> inet_addrs;
  std::map<std::string, std::set<in_addr_t>> broad_addrs;

  // Collect the IPv4 addresses for each interface.
  ifaddrs* addrs;
  ASSERT_EQ(0, getifaddrs(&addrs));
  for (ifaddrs* addr = addrs; addr != nullptr; addr = addr->ifa_next) {
    if (addr->ifa_name && addr->ifa_addr && addr->ifa_addr->sa_family == AF_INET) {
      auto sock = reinterpret_cast<sockaddr_in*>(addr->ifa_addr);
      inet_addrs[addr->ifa_name].insert(sock->sin_addr.s_addr);
    }
    if (addr->ifa_name && addr->ifa_broadaddr && addr->ifa_broadaddr->sa_family == AF_INET) {
      auto sock = reinterpret_cast<sockaddr_in*>(addr->ifa_broadaddr);
      broad_addrs[addr->ifa_name].insert(sock->sin_addr.s_addr);
    }
  }
  freeifaddrs(addrs);

  // Check that the addresses returned by the SIOCGIFADDR and SIOCGIFBRDADDR/SIOCGIFDSTADDR ioctls
  // are in our collections.
  for (const auto& it : inet_addrs) CheckAddressIsInSet(it.first, true, it.second);
  for (const auto& it : broad_addrs) CheckAddressIsInSet(it.first, false, it.second);
}

static void print_sockaddr_ll(const char* what, const sockaddr* p) {
  const sockaddr_ll* s = reinterpret_cast<const sockaddr_ll*>(p);
  printf("\t\t%s\t", what);
  for (int i = 0; i < s->sll_halen; ++i) {
    if (i > 0) printf(":");
    printf("%02X", s->sll_addr[i]);
  }
  printf(" (%d bytes)\n", s->sll_halen);
}

static void print_sockaddr_inet(const char* what, const sockaddr* addr) {
  char host[NI_MAXHOST];
  int family = addr->sa_family;
  int error = getnameinfo(addr,
                          (family == AF_INET) ? sizeof(sockaddr_in) : sizeof(sockaddr_in6),
                          host, NI_MAXHOST, nullptr, 0, NI_NUMERICHOST);
  if (error != 0) {
    printf("%d getnameinfo() failed: %s\n", family, gai_strerror(error));
    strcpy(host, "???");
  }
  printf("\t\t%s: <%s>\n", what, host);
}

static const char* FamilyToName(int family) {
  if (family == AF_INET) return "AF_INET";
  if (family == AF_INET6) return "AF_INET6";
  if (family == AF_PACKET) return "AF_PACKET";
  if (family == AF_UNSPEC) return "AF_UNSPEC";
  return "?";
}

static std::string FlagsToString(short flags) {
  std::string result;
  if ((flags & IFF_UP) != 0) result += " UP";
  if ((flags & IFF_BROADCAST) != 0) result += " BROADCAST";
  if ((flags & IFF_DEBUG) != 0) result += " DEBUG";
  if ((flags & IFF_LOOPBACK) != 0) result += " LOOPBACK";
  if ((flags & IFF_POINTOPOINT) != 0) result += " POINTOPOINT";
  if ((flags & IFF_NOTRAILERS) != 0) result += " NOTRAILERS";
  if ((flags & IFF_RUNNING) != 0) result += " RUNNING";
  if ((flags & IFF_NOARP) != 0) result += " NOARP";
  if ((flags & IFF_PROMISC) != 0) result += " PROMISC";
  if ((flags & IFF_ALLMULTI) != 0) result += " ALLMULTI";
  if ((flags & IFF_MASTER) != 0) result += " MASTER";
  if ((flags & IFF_SLAVE) != 0) result += " SLAVE";
  if ((flags & IFF_MULTICAST) != 0) result += " MULTICAST";
  if ((flags & IFF_PORTSEL) != 0) result += " PORTSEL";
  if ((flags & IFF_AUTOMEDIA) != 0) result += " AUTOMEDIA";
  if ((flags & IFF_DYNAMIC) != 0) result += " DYNAMIC";
  if ((flags & IFF_LOWER_UP) != 0) result += " LOWER_UP";
  if ((flags & IFF_DORMANT) != 0) result += " DORMANT";
  if ((flags & IFF_ECHO) != 0) result += " ECHO";
  return result;
}

// Not really a test, but a useful debugging tool.
TEST(ifaddrs, dump) {
  ifaddrs* addrs;
  ASSERT_EQ(0, getifaddrs(&addrs));

  for (ifaddrs* ifa = addrs; ifa != nullptr; ifa = ifa->ifa_next) {
    int family = ifa->ifa_addr ? ifa->ifa_addr->sa_family :
                                 ifa->ifa_broadaddr ? ifa->ifa_broadaddr->sa_family : AF_UNSPEC;

    printf("\t%s\n"
           "\t\t%s (%d) flags=%#x%s\n",
           ifa->ifa_name, FamilyToName(family), family,
           ifa->ifa_flags, FlagsToString(ifa->ifa_flags).c_str());

    if (family == AF_PACKET) {
      if (ifa->ifa_addr) print_sockaddr_ll("hwaddr", ifa->ifa_addr);
      if (ifa->ifa_broadaddr) print_sockaddr_ll("hwbroad", ifa->ifa_addr);
    } else if (family == AF_INET || family == AF_INET6) {
      if (ifa->ifa_addr) print_sockaddr_inet("address", ifa->ifa_addr);
      if (ifa->ifa_broadaddr && (ifa->ifa_flags & (IFF_BROADCAST | IFF_POINTOPOINT)) != 0) {
        print_sockaddr_inet((ifa->ifa_flags & IFF_BROADCAST) ? "broadcast" : "destination",
                            ifa->ifa_broadaddr);
      }
    }

    fflush(stdout);
  }

  freeifaddrs(addrs);
}

TEST(ifaddrs, inet6_scope_ids) {
  ifaddrs* addrs;
  ASSERT_EQ(0, getifaddrs(&addrs));

  for (ifaddrs* ifa = addrs; ifa != nullptr; ifa = ifa->ifa_next) {
    if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET6) {
      sockaddr_in6* sa6 = reinterpret_cast<sockaddr_in6*>(ifa->ifa_addr);
      // Any link-local IPv6 address should have a scope id. (http://b/27219454.)
      // 0 isn't a valid interface index, so that would mean the scope id wasn't set.
      if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&sa6->sin6_addr)) {
        ASSERT_NE(sa6->sin6_scope_id, 0U);
      }
    }
  }

  freeifaddrs(addrs);
}

TEST(ifaddrs, kernel_bug_31038971) {
  // Some kernels had a bug that would lead to an NLMSG_ERROR response,
  // but bionic wasn't setting errno based on the value in the message.
  // This is the test for the kernel bug, but on a device with a bad
  // kernel this test was also useful for testing the bionic errno fix.
  std::vector<std::thread*> threads;
  for (size_t i = 0; i < 128; ++i) {
    threads.push_back(new std::thread([]() {
      ifaddrs* addrs = nullptr;
      ASSERT_EQ(0, getifaddrs(&addrs)) << strerror(errno);
      freeifaddrs(addrs);
    }));
  }
  for (auto& t : threads) {
    t->join();
    delete t;
  }
}

TEST(ifaddrs, errno_EMFILE) {
  std::vector<int> fds;
  while (true) {
    int fd = open("/dev/null", O_RDONLY|O_CLOEXEC);
    if (fd == -1) {
      ASSERT_ERRNO(EMFILE);
      break;
    }
    fds.push_back(fd);
  }

  ifaddrs* addrs;
  EXPECT_EQ(-1, getifaddrs(&addrs));
  EXPECT_ERRNO(EMFILE);

  for (int fd : fds) close(fd);
}
