// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ip_address.h"

#include <stdlib.h>
#include <string.h>
#include <climits>

#include "check.h"

namespace bssl {

namespace fillins {

IPAddress::IPAddress() {}

IPAddress::IPAddress(const uint8_t *address, size_t address_len)
    : addr_(reinterpret_cast<const char *>(address), address_len) {}

IPAddress::IPAddress(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3) {
  addr_.reserve(4);
  addr_.push_back(b0);
  addr_.push_back(b1);
  addr_.push_back(b2);
  addr_.push_back(b3);
}

IPAddress::IPAddress(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4,
                     uint8_t b5, uint8_t b6, uint8_t b7, uint8_t b8, uint8_t b9,
                     uint8_t b10, uint8_t b11, uint8_t b12, uint8_t b13,
                     uint8_t b14, uint8_t b15) {
  addr_.reserve(16);
  addr_.push_back(b0);
  addr_.push_back(b1);
  addr_.push_back(b2);
  addr_.push_back(b3);
  addr_.push_back(b4);
  addr_.push_back(b5);
  addr_.push_back(b6);
  addr_.push_back(b7);
  addr_.push_back(b8);
  addr_.push_back(b9);
  addr_.push_back(b10);
  addr_.push_back(b11);
  addr_.push_back(b12);
  addr_.push_back(b13);
  addr_.push_back(b14);
  addr_.push_back(b15);
}

// static
IPAddress IPAddress::AllZeros(size_t num_zero_bytes) {
  CHECK_LE(num_zero_bytes, 16u);
  IPAddress result;
  result.addr_.reserve(num_zero_bytes);
  for (size_t i = 0; i < num_zero_bytes; ++i) {
    result.addr_.push_back(0u);
  }
  return result;
}

// static
IPAddress IPAddress::IPv4AllZeros() { return AllZeros(kIPv4AddressSize); }

bool IPAddress::IsIPv4() const { return addr_.size() == kIPv4AddressSize; }

bool IPAddress::IsIPv6() const { return addr_.size() == kIPv6AddressSize; }

bool IPAddress::IsValid() const { return IsIPv4() || IsIPv6(); }

const uint8_t *IPAddress::data() const {
  return reinterpret_cast<const uint8_t *>(addr_.data());
}

size_t IPAddress::size() const { return addr_.size(); }

const IPAddressBytes &IPAddress::bytes() const { return addr_; }

static IPAddress ConvertIPv4ToIPv4MappedIPv6(const IPAddress &address) {
  CHECK(address.IsIPv4());
  // IPv4-mapped addresses are formed by:
  // <80 bits of zeros>  + <16 bits of ones> + <32-bit IPv4 address>.
  uint8_t bytes[16];
  memset(bytes, 0, 10);
  memset(bytes + 10, 0xff, 2);
  memcpy(bytes + 12, address.data(), address.size());
  return IPAddress(bytes, sizeof(bytes));
}

// Note that this function assumes:
// * |ip_address| is at least |prefix_length_in_bits| (bits) long;
// * |ip_prefix| is at least |prefix_length_in_bits| (bits) long.
static bool IPAddressPrefixCheck(const uint8_t *ip_address,
                                 const uint8_t *ip_prefix,
                                 size_t prefix_length_in_bits) {
  // Compare all the bytes that fall entirely within the prefix.
  size_t num_entire_bytes_in_prefix = prefix_length_in_bits / 8;
  for (size_t i = 0; i < num_entire_bytes_in_prefix; ++i) {
    if (ip_address[i] != ip_prefix[i]) {
      return false;
    }
  }

  // In case the prefix was not a multiple of 8, there will be 1 byte
  // which is only partially masked.
  size_t remaining_bits = prefix_length_in_bits % 8;
  if (remaining_bits != 0) {
    uint8_t mask = 0xFF << (8 - remaining_bits);
    size_t i = num_entire_bytes_in_prefix;
    if ((ip_address[i] & mask) != (ip_prefix[i] & mask)) {
      return false;
    }
  }

  return true;
}

bool IPAddressMatchesPrefix(const IPAddress &ip_address,
                            const IPAddress &ip_prefix,
                            size_t prefix_length_in_bits) {
  // Both the input IP address and the prefix IP address should be either IPv4
  // or IPv6.
  DCHECK(ip_address.IsValid());
  DCHECK(ip_prefix.IsValid());

  DCHECK_LE(prefix_length_in_bits, ip_prefix.size() * 8);

  // In case we have an IPv6 / IPv4 mismatch, convert the IPv4 addresses to
  // IPv6 addresses in order to do the comparison.
  if (ip_address.size() != ip_prefix.size()) {
    if (ip_address.IsIPv4()) {
      return IPAddressMatchesPrefix(ConvertIPv4ToIPv4MappedIPv6(ip_address),
                                    ip_prefix, prefix_length_in_bits);
    }
    return IPAddressMatchesPrefix(ip_address,
                                  ConvertIPv4ToIPv4MappedIPv6(ip_prefix),
                                  96 + prefix_length_in_bits);
  }

  return IPAddressPrefixCheck(ip_address.data(), ip_prefix.data(),
                              prefix_length_in_bits);
}

static unsigned CommonPrefixLength(const IPAddress &a1, const IPAddress &a2) {
  DCHECK_EQ(a1.size(), a2.size());
  for (size_t i = 0; i < a1.size(); ++i) {
    uint8_t diff = a1.bytes()[i] ^ a2.bytes()[i];
    if (!diff)
      continue;
    for (unsigned j = 0; j < CHAR_BIT; ++j) {
      if (diff & (1 << (CHAR_BIT - 1)))
        return i * CHAR_BIT + j;
      diff <<= 1;
    }
    abort();
  }
  return a1.size() * CHAR_BIT;
}

unsigned MaskPrefixLength(const IPAddress &mask) {
  uint8_t all_ones[16];
  const size_t mask_len = std::min(mask.size(), sizeof(all_ones));
  memset(all_ones, 0xff, mask_len);
  return CommonPrefixLength(mask, IPAddress(all_ones, mask_len));
}

}  // namespace fillins

}  // namespace bssl
