// Copyright 2018 The Chromium OS 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 <string.h>

#include <errno.h>
#include <net/ethernet.h>  // L2 stuff.
#include <net/if_arp.h>    // ARPHRD_* definitions.
#include <sys/ioctl.h>

#include <base/logging.h>
#include <base/posix/safe_strerror.h>
#include <base/strings/stringprintf.h>

#include <shill/net/byte_string.h>

#include "portier/network_socket.h"

namespace portier {

using std::string;
using base::safe_strerror;
using shill::ByteString;

using Code = Status::Code;

using State = NetworkSocket::State;

namespace {

// Used for ioctl() calls.
constexpr int kTrue = true;
constexpr int kFalse = false;

}  // namespace

string NetworkSocket::GetStateName(State state) {
  switch (state) {
    case State::UNINITIALIZED:
      return "Unitialized";
    case State::READY:
      return "Ready";
    case State::CLOSED:
      return "Closed";
  }
  return base::StringPrintf("Unknown (%d)", static_cast<int>(state));
}

NetworkSocket::NetworkSocket(const string& if_name)
    : name_(if_name), index_(-1), fd_(-1), state_(State::UNINITIALIZED) {}

// State getters.

// private.
bool NetworkSocket::IsUnitialized() const {
  return state() == State::UNINITIALIZED;
}

bool NetworkSocket::IsReady() const {
  return state() == State::READY;
}

bool NetworkSocket::IsClosed() const {
  return state() == State::CLOSED;
}

Status NetworkSocket::Close() {
  if (IsUnitialized()) {
    return Status(Code::BAD_INTERNAL_STATE,
                  "Cannot close an uninitialized socket");
  }
  if (IsClosed()) {
    return Status();
  }

  CloseFd();
  state_ = State::CLOSED;

  return Status();
}

void NetworkSocket::CloseFd() {
  if (fd() != -1) {
    close(fd_);
    fd_ = -1;
  }
}

// Interface information getters.

Status NetworkSocket::GetLinkLayerAddress(LLAddress* ll_address) const {
  DCHECK(ll_address != nullptr)
      << "Output parameter `ll_address' cannot be null";
  if (!IsReady()) {
    return Status(Code::BAD_INTERNAL_STATE) << "Socket is not ready";
  }

  struct ifreq ifreq;
  PrepareIfRequestStruct(&ifreq);
  if (ioctl(fd(), SIOCGIFHWADDR, &ifreq) < 0) {
    const int saved_errno = errno;
    return Status(Code::UNEXPECTED_FAILURE)
           << "Failed to get interface hardware address: ioctl(): "
           << safe_strerror(saved_errno);
  }

  // TODO(sigquit): figure out how to validate the device type
  //  (ifreq.ifr_hwaddr.sa_family) is supported by the current framework.
  //  A list of possible values can be found in <linux/if_arp.h>, using the
  //  ARPHRD_* list.  Good luck!
  //  For now, going to just assume the only valid option is ARPHRD_ETHER.
  if (ARPHRD_ETHER != ifreq.ifr_hwaddr.sa_family) {
    return Status(Code::UNSUPPORTED_TYPE)
           << "Hardware type is not supported: "
           << base::StringPrintf("Got ARPHRD id %d",
                                 ifreq.ifr_hwaddr.sa_family);
  }

  *ll_address = LLAddress(LLAddress::kTypeEui48,
                          ByteString(ifreq.ifr_hwaddr.sa_data, ETHER_ADDR_LEN));

  return Status();
}

Status NetworkSocket::GetLinkMTU(uint32_t* mtu) const {
  DCHECK(mtu != nullptr) << "Output parameter `mtu' cannot be null";
  if (!IsReady()) {
    return Status(Code::BAD_INTERNAL_STATE) << "Socket is not ready";
  }

  struct ifreq ifreq;
  PrepareIfRequestStruct(&ifreq);
  if (ioctl(fd(), SIOCGIFMTU, &ifreq) < 0) {
    const int saved_errno = errno;
    return Status(Code::UNEXPECTED_FAILURE)
           << "Failed to get interface MTU: ioctl(): "
           << safe_strerror(saved_errno);
  }

  *mtu = static_cast<uint32_t>(ifreq.ifr_mtu);
  return Status();
}

Status NetworkSocket::GetLoopbackFlag(bool* loopback_flag) const {
  DCHECK(loopback_flag != nullptr)
      << "Output parameter `loopback_flag' cannot be null";
  if (!IsReady()) {
    return Status(Code::BAD_INTERNAL_STATE) << "Socket is not ready";
  }

  int16_t flags = 0;
  PORTIER_RETURN_ON_FAILURE(GetInterfaceFlags(&flags))
      << "Failed to get loopback flag";

  *loopback_flag = ((flags & IFF_LOOPBACK) != 0);
  return Status();
}

Status NetworkSocket::SetNonBlockingMode(bool enabled) {
  if (!IsReady()) {
    return Status(Code::BAD_INTERNAL_STATE) << "Socket is not ready";
  }

  if (ioctl(fd(), FIONBIO, enabled ? &kTrue : &kFalse) < 0) {
    const int saved_errno = errno;
    return Status(Code::UNEXPECTED_FAILURE)
           << "Failed to set non-blocking mode enabled "
           << (enabled ? "true" : "false")
           << ": setsockopt(): " << safe_strerror(saved_errno);
  }
  return Status();
}

// private.
void NetworkSocket::PrepareIfRequestStruct(struct ifreq* ifreq) const {
  DCHECK(ifreq != nullptr);
  memset(ifreq, 0, sizeof(struct ifreq));
  strncpy(ifreq->ifr_name, name().c_str(), IFNAMSIZ - 1);
}

// private.
Status NetworkSocket::SetInterfaceFlags(int16_t flags) {
  if (!IsReady()) {
    return Status(Code::BAD_INTERNAL_STATE) << "Socket is not ready";
  }

  struct ifreq ifreq;
  PrepareIfRequestStruct(&ifreq);
  ifreq.ifr_flags = flags;
  if (ioctl(fd(), SIOCSIFFLAGS, &ifreq) < 0) {
    const int saved_errno = errno;
    return Status(Code::UNEXPECTED_FAILURE)
           << "Failed to set interface flags: ioctl(): "
           << safe_strerror(saved_errno);
  }

  return Status();
}

// private.
Status NetworkSocket::GetInterfaceFlags(int16_t* flags) const {
  DCHECK(flags != nullptr) << "Output parameter `flags' cannot be null";
  if (!IsReady()) {
    return Status(Code::BAD_INTERNAL_STATE) << "Socket is not ready";
  }

  struct ifreq ifreq;
  PrepareIfRequestStruct(&ifreq);
  if (ioctl(fd(), SIOCGIFFLAGS, &ifreq) < 0) {
    const int saved_errno = errno;
    return Status(Code::UNEXPECTED_FAILURE)
           << "Failed to get interface flags: ioctl(): "
           << safe_strerror(saved_errno);
  }

  *flags = ifreq.ifr_flags;
  return Status();
}

}  // namespace portier
