// Copyright 2018 The Fuchsia 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 <ddk/protocol/ethernet.h>
#include <fbl/auto_call.h>
#include <fuchsia/net/stack/cpp/fidl.h>
#include <fuchsia/netstack/cpp/fidl.h>
#include <lib/fdio/util.h>
#include <lib/fdio/watcher.h>
#include <lib/fidl/cpp/interface_handle.h>
#include <lib/zx/socket.h>
#include <zircon/device/ethertap.h>
#include <zircon/ethernet/cpp/fidl.h>
#include <zircon/status.h>
#include <zircon/types.h>

#include <string>

#include <fcntl.h>
#include <inttypes.h>
#include <stdio.h>
#include <string.h>

#include "gtest/gtest.h"

#include "lib/component/cpp/testing/test_util.h"
#include "lib/component/cpp/testing/test_with_environment.h"

namespace {
class NetstackLaunchTest : public component::testing::TestWithEnvironment {};

const char kEthernetDir[] = "/dev/class/ethernet";
const char kTapctl[] = "/dev/misc/tapctl";
const uint8_t kTapMac[] = {0x12, 0x20, 0x30, 0x40, 0x50, 0x60};

zx_status_t CreateEthertap(zx::socket* sock) {
  int ctlfd = open(kTapctl, O_RDONLY);
  if (ctlfd < 0) {
    fprintf(stderr, "could not open %s: %s\n", kTapctl, strerror(errno));
    return ZX_ERR_IO;
  }
  auto closer = fbl::MakeAutoCall([ctlfd]() { close(ctlfd); });

  ethertap_ioctl_config_t config = {};
  strlcpy(config.name, "netstack_add_eth_test", ETHERTAP_MAX_NAME_LEN);
  config.mtu = 1500;
  memcpy(config.mac, kTapMac, 6);
  ssize_t rc =
      ioctl_ethertap_config(ctlfd, &config, sock->reset_and_get_address());
  if (rc < 0) {
    zx_status_t status = static_cast<zx_status_t>(rc);
    fprintf(stderr, "could not configure ethertap device: %s\n",
            zx_status_get_string(status));
    return status;
  }
  return ZX_OK;
}

zx_status_t WatchCb(int dirfd, int event, const char* fn, void* cookie) {
  if (event != WATCH_EVENT_ADD_FILE) {
    return ZX_OK;
  }
  if (!strcmp(fn, ".") || !strcmp(fn, "..")) {
    return ZX_OK;
  }

  zx::channel svc;
  {
    int devfd = openat(dirfd, fn, O_RDONLY);
    if (devfd < 0) {
      return ZX_OK;
    }

    zx_status_t status =
        fdio_get_service_handle(devfd, svc.reset_and_get_address());
    if (status != ZX_OK) {
      return status;
    }
  }

  ::zircon::ethernet::Device_SyncProxy dev(std::move(svc));
  // See if this device is our ethertap device
  zircon::ethernet::Info info;
  zx_status_t status = dev.GetInfo(&info);
  if (status != ZX_OK) {
    fprintf(stderr, "could not get ethernet info for %s/%s: %s\n", kEthernetDir,
            fn, zx_status_get_string(status));
    // Return ZX_OK to keep watching for devices.
    return ZX_OK;
  }
  if (!(info.features & zircon::ethernet::INFO_FEATURE_SYNTH)) {
    // Not a match, keep looking.
    return ZX_OK;
  }

  // Found it!
  // TODO(tkilbourn): this might not be the test device we created; need a
  // robust way of getting the name of the tap device to check. Note that
  // ioctl_device_get_device_name just returns "ethernet" since that's the child
  // of the tap device that we've opened here.
  auto svcp = reinterpret_cast<zx_handle_t*>(cookie);
  *svcp = dev.proxy().TakeChannel().release();
  return ZX_ERR_STOP;
}

zx_status_t OpenEthertapDev(zx::channel* svc) {
  if (svc == nullptr) {
    return ZX_ERR_INVALID_ARGS;
  }

  int ethdir = open(kEthernetDir, O_RDONLY);
  if (ethdir < 0) {
    fprintf(stderr, "could not open %s: %s\n", kEthernetDir, strerror(errno));
    return ZX_ERR_IO;
  }

  zx_status_t status;
  status = fdio_watch_directory(
      ethdir, WatchCb, zx_deadline_after(ZX_SEC(2)),
      reinterpret_cast<void*>(svc->reset_and_get_address()));
  if (status == ZX_ERR_STOP) {
    return ZX_OK;
  } else {
    return status;
  }
}

TEST_F(NetstackLaunchTest, AddEthernetDevice) {
  auto services = CreateServices();

  // TODO(NET-1818): parameterize this over multiple netstack implementations
  fuchsia::sys::LaunchInfo launch_info;
  launch_info.url = "netstack";
  launch_info.out = component::testing::CloneFileDescriptor(1);
  launch_info.err = component::testing::CloneFileDescriptor(2);
  services->AddServiceWithLaunchInfo(std::move(launch_info),
                                     fuchsia::net::stack::Stack::Name_);

  auto env = CreateNewEnclosingEnvironment("NetstackLaunchTest_AddEth",
                                           std::move(services));
  ASSERT_TRUE(WaitForEnclosingEnvToStart(env.get()));

  zx::socket sock;
  zx_status_t status = CreateEthertap(&sock);
  ASSERT_EQ(ZX_OK, status) << zx_status_get_string(status);
  zx::channel svc;
  status = OpenEthertapDev(&svc);
  ASSERT_EQ(ZX_OK, status) << zx_status_get_string(status);
  fprintf(stderr, "found tap device\n");

  bool list_ifs = false;
  fuchsia::net::stack::StackPtr stack;
  env->ConnectToService(stack.NewRequest());
  stack->ListInterfaces(
      [&](::fidl::VectorPtr<::fuchsia::net::stack::InterfaceInfo> interfaces) {
        for (const auto& iface : *interfaces) {
          ASSERT_TRUE(iface.features &
                      ::zircon::ethernet::INFO_FEATURE_LOOPBACK);
        }
        list_ifs = true;
      });
  ASSERT_TRUE(RunLoopWithTimeoutOrUntil([&] { return list_ifs; }, zx::sec(5)));

  uint64_t eth_id = 0;
  fidl::StringPtr topo_path = "/fake/device";
  stack->AddEthernetInterface(
      std::move(topo_path),
      fidl::InterfaceHandle<::zircon::ethernet::Device>(std::move(svc)),
      [&](std::unique_ptr<::fuchsia::net::stack::Error> err, uint64_t id) {
        if (err != nullptr) {
          fprintf(stderr, "error adding ethernet interface: %u\n",
                  static_cast<uint32_t>(err->type));
        } else {
          eth_id = id;
        }
      });
  ASSERT_TRUE(
      RunLoopWithTimeoutOrUntil([&] { return eth_id > 0; }, zx::sec(5)));

  list_ifs = false;
  stack->ListInterfaces(
      [&](::fidl::VectorPtr<::fuchsia::net::stack::InterfaceInfo> interfaces) {
        for (const auto& iface : *interfaces) {
          if (iface.features & ::zircon::ethernet::INFO_FEATURE_LOOPBACK) {
            continue;
          }
          ASSERT_EQ(eth_id, iface.id);
        }
        list_ifs = true;
      });
  ASSERT_TRUE(RunLoopWithTimeoutOrUntil([&] { return list_ifs; }, zx::sec(5)));
}

TEST_F(NetstackLaunchTest, DISABLED_DHCPRequestSent) {
  auto services = CreateServices();

  // TODO(NET-1818): parameterize this over multiple netstack implementations
  fuchsia::sys::LaunchInfo launch_info;
  launch_info.url = "netstack";
  launch_info.out = component::testing::CloneFileDescriptor(1);
  launch_info.err = component::testing::CloneFileDescriptor(2);
  zx_status_t status = services->AddServiceWithLaunchInfo(
      std::move(launch_info), fuchsia::netstack::Netstack::Name_);
  ASSERT_EQ(status, ZX_OK) << zx_status_get_string(status);

  auto env = CreateNewEnclosingEnvironment("NetstackDHCPTest_RequestSent",
                                           std::move(services));
  ASSERT_TRUE(WaitForEnclosingEnvToStart(env.get()));

  zx::socket sock;
  status = CreateEthertap(&sock);
  ASSERT_EQ(ZX_OK, status) << zx_status_get_string(status);
  zx::channel svc;
  status = OpenEthertapDev(&svc);
  ASSERT_EQ(ZX_OK, status) << zx_status_get_string(status);
  fprintf(stderr, "found tap device\n");

  status = sock.signal_peer(0u, ETHERTAP_SIGNAL_ONLINE);
  ASSERT_EQ(ZX_OK, status) << zx_status_get_string(status);
  fprintf(stderr, "set ethertap link status online\n");

  fuchsia::netstack::NetstackPtr netstack;
  env->ConnectToService(netstack.NewRequest());
  fidl::StringPtr topo_path = "/fake/device";

  fidl::StringPtr interface_name = "dhcp_test_interface";
  fuchsia::netstack::InterfaceConfig config =
      fuchsia::netstack::InterfaceConfig{};
  config.name = interface_name;
  config.ip_address_config.set_dhcp(true);

  // TODO(NET-1864): migrate to fuchsia.net.stack.AddEthernetInterface when we
  // migrate netcfg to use AddEthernetInterface.
  netstack->AddEthernetDevice(
      std::move(topo_path), std::move(config),
      fidl::InterfaceHandle<::zircon::ethernet::Device>(std::move(svc)));

  // Give zx_channel_write 10ms to enqueue whatever it needs, then run
  // until idle (reduces flake rate to zero).
  //
  // TODO(NET-1967): Figure out why this sleep is required. The call stack in
  // AddEthernetDevice is AddEthernetDevice -> ProxyController#Send ->
  // Message#Write -> zx_channel_write, none of which are asynchronous.
  zx::nanosleep(zx::deadline_after(zx::msec(10)));
  RealLoopFixture::RunLoopUntilIdle();

  std::byte buf[1500];
  size_t attempt_to_read = 1500;
  size_t read;
  size_t parsed = 0;
  zx_signals_t pending = 0;

  // Expected to take about ~150ms; we're being conservative to avoid flakes.
  status = sock.wait_one(ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED |
                             ZX_SOCKET_PEER_WRITE_DISABLED,
                         zx::clock::get_monotonic() + zx::msec(500), &pending);

  ASSERT_EQ(ZX_OK, status) << zx_status_get_string(status);
  ASSERT_GT((pending & ZX_SOCKET_READABLE), 0u)
      << "socket was not readable; signals: " << pending;
  status = sock.read(0, buf, attempt_to_read, &read);

  ASSERT_EQ(ZX_OK, status) << zx_status_get_string(status);
  ASSERT_GT(read, (size_t)0);
  EXPECT_EQ(read, (size_t)310)
      << "read " << read << " bytes of " << attempt_to_read << " requested\n";

  EXPECT_EQ((unsigned int)buf[0], ETHERTAP_MSG_PACKET)
      << "ethertap packet header incorrect";

  std::byte* eth = &buf[sizeof(ethertap_socket_header_t)];
  parsed += sizeof(ethertap_socket_header_t);
  std::byte ethertype = eth[12];
  EXPECT_EQ((int)ethertype, 0x08);

  // TODO(stijlist): add an ETH_FRAME_MIN_HDR_SIZE to ddk's ethernet.h
  size_t eth_frame_min_hdr_size = 14;
  std::byte* ip = &eth[eth_frame_min_hdr_size];
  parsed += eth_frame_min_hdr_size;
  std::byte protocol_number = ip[9];
  EXPECT_EQ((int)protocol_number, 17);

  size_t ihl = (size_t)(ip[0] & (std::byte)0x0f);
  size_t ip_bytes = (ihl * 32u) / 8u;

  std::byte* udp = &ip[ip_bytes];
  parsed += ip_bytes;

  uint16_t src_port = (uint16_t)udp[0] << 8 | (uint8_t)udp[1];
  uint16_t dst_port = (uint16_t)udp[2] << 8 | (uint8_t)udp[3];

  // DHCP requests from netstack should come from port 68 (DHCP client) to port
  // 67 (DHCP server).
  EXPECT_EQ(src_port, 68u);
  EXPECT_EQ(dst_port, 67u);

  std::byte* dhcp = &udp[8];
  // Assert the DHCP op type is DHCP request.
  std::byte dhcp_op_type = dhcp[0];
  EXPECT_EQ((int)dhcp_op_type, 0x01);
}
}  // namespace
