// 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 "shill/icmp.h"

#include <netinet/icmp6.h>
#include <netinet/ip_icmp.h>

#include "shill/logging.h"
#include "shill/net/sockets.h"

namespace shill {

const int Icmp::kIcmpEchoCode = 0;  // value specified in RFC 792.

Icmp::Icmp()
    : sockets_(new Sockets()),
      socket_(-1),
      destination_(IPAddress::kFamilyUnknown),
      interface_index_(-1) {}

Icmp::~Icmp() {}

bool Icmp::Start(const IPAddress& destination, int interface_index) {
  if (!destination.IsValid()) {
    LOG(ERROR) << "Destination address is not valid.";
    return false;
  }

  int socket = -1;
  if (destination.family() == IPAddress::kFamilyIPv4) {
    socket = sockets_->Socket(AF_INET, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMP);
  } else if (destination.family() == IPAddress::kFamilyIPv6) {
    socket = sockets_->Socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC,
        IPPROTO_ICMPV6);
  } else {
    NOTREACHED();
  }

  if (socket == -1) {
    PLOG(ERROR) << "Could not create ICMP socket";
    Stop();
    return false;
  }
  socket_ = socket;
  socket_closer_.reset(new ScopedSocketCloser(sockets_.get(), socket_));

  if (sockets_->SetNonBlocking(socket_) != 0) {
    PLOG(ERROR) << "Could not set socket to be non-blocking";
    Stop();
    return false;
  }

  destination_ = destination;
  interface_index_ = interface_index;
  return true;
}

void Icmp::Stop() {
  socket_closer_.reset();
  socket_ = -1;
}

bool Icmp::IsStarted() const {
  return socket_closer_.get();
}

bool Icmp::TransmitV4EchoRequest(uint16_t id, uint16_t seq_num) {
  struct icmphdr icmp_header;
  memset(&icmp_header, 0, sizeof(icmp_header));
  icmp_header.type = ICMP_ECHO;
  icmp_header.code = kIcmpEchoCode;
  icmp_header.un.echo.id = id;
  icmp_header.un.echo.sequence = seq_num;
  icmp_header.checksum = ComputeIcmpChecksum(icmp_header, sizeof(icmp_header));

  struct sockaddr_in destination_address;
  destination_address.sin_family = AF_INET;
  CHECK_EQ(sizeof(destination_address.sin_addr.s_addr),
           destination_.GetLength());
  memcpy(&destination_address.sin_addr.s_addr,
         destination_.address().GetConstData(),
         sizeof(destination_address.sin_addr.s_addr));

  int result = sockets_->SendTo(
      socket_,
      &icmp_header,
      sizeof(icmp_header),
      0,
      reinterpret_cast<struct sockaddr*>(&destination_address),
      sizeof(destination_address));
  int expected_result = sizeof(icmp_header);
  if (result != expected_result) {
    if (result < 0) {
      PLOG(ERROR) << "Socket sendto failed";
    } else if (result < expected_result) {
      LOG(ERROR) << "Socket sendto returned "
                 << result
                 << " which is less than the expected result "
                 << expected_result;
    }
    return false;
  }

  return true;
}

bool Icmp::TransmitV6EchoRequest(uint16_t id, uint16_t seq_num) {
  struct icmp6_hdr icmp_header;
  memset(&icmp_header, 0, sizeof(icmp_header));
  icmp_header.icmp6_type = ICMP6_ECHO_REQUEST;
  icmp_header.icmp6_code = kIcmpEchoCode;
  icmp_header.icmp6_id = id;
  icmp_header.icmp6_seq = seq_num;
  // icmp6_cksum is filled in by the kernel for IPPROTO_ICMPV6 sockets
  // (RFC3542 section 3.1)

  struct sockaddr_in6 destination_address;
  memset(&destination_address, 0, sizeof(destination_address));
  destination_address.sin6_family = AF_INET6;
  destination_address.sin6_scope_id = interface_index_;
  CHECK_EQ(sizeof(destination_address.sin6_addr.s6_addr),
           destination_.GetLength());
  memcpy(&destination_address.sin6_addr.s6_addr,
         destination_.address().GetConstData(),
         sizeof(destination_address.sin6_addr.s6_addr));

  int result =
      sockets_->SendTo(socket_,
                       &icmp_header,
                       sizeof(icmp_header),
                       0,
                       reinterpret_cast<struct sockaddr*>(&destination_address),
                       sizeof(destination_address));
  int expected_result = sizeof(icmp_header);
  if (result != expected_result) {
    if (result < 0) {
      PLOG(ERROR) << "Socket sendto failed";
    } else if (result < expected_result) {
      LOG(ERROR) << "Socket sendto returned " << result
                 << " which is less than the expected result "
                 << expected_result;
    }
    return false;
  }

  return true;
}

bool Icmp::TransmitEchoRequest(uint16_t id, uint16_t seq_num) {
  if (!IsStarted()) {
    return false;
  }

  if (destination_.family() == IPAddress::kFamilyIPv4) {
    return TransmitV4EchoRequest(id, seq_num);
  } else {
    return TransmitV6EchoRequest(id, seq_num);
  }
}

// static
uint16_t Icmp::ComputeIcmpChecksum(const struct icmphdr& hdr, size_t len) {
  // Compute Internet Checksum for "len" bytes beginning at location "hdr".
  // Adapted directly from the canonical implementation in RFC 1071 Section 4.1.
  uint32_t sum = 0;
  const uint16_t* addr = reinterpret_cast<const uint16_t*>(&hdr);

  while (len > 1) {
    sum += *addr;
    ++addr;
    len -= sizeof(*addr);
  }

  // Add left-over byte, if any.
  if (len > 0) {
    sum += *reinterpret_cast<const uint8_t*>(addr);
  }

  // Fold 32-bit sum to 16 bits.
  while (sum >> 16) {
    sum = (sum & 0xffff) + (sum >> 16);
  }

  return static_cast<uint16_t>(~sum);
}

}  // namespace shill
