// Copyright 2017 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 "src/lib/inet/ip_address.h"

#include <arpa/inet.h>
#include <endian.h>
#include <sys/socket.h>

#include <sstream>

namespace inet {
namespace {

// Parses a string. Match functions either return true and update the position
// of the parser or return false and leave the position unchanged.
class Parser {
 public:
  Parser(const std::string& str) : str_(str), pos_(0) {}

  // Matches end-of-string.
  bool MatchEnd() { return pos_ == str_.length(); }

  // Matches a specified character.
  bool Match(char to_match) {
    if (pos_ == str_.length() || str_[pos_] != to_match) {
      return false;
    }

    ++pos_;

    return true;
  }

  // Matches a single decimal digit.
  bool MatchDecDigit(uint8_t* out) {
    FX_DCHECK(out);

    if (pos_ == str_.length() || !std::isdigit(static_cast<unsigned char>(str_[pos_]))) {
      return false;
    }

    *out = str_[pos_] - '0';
    ++pos_;

    return true;
  }

  // Matches a single lowercase hexadecimal digit.
  bool MatchLowerHexDigit(uint8_t* out) {
    FX_DCHECK(out);

    if (pos_ == str_.length() || !std::isxdigit(static_cast<unsigned char>(str_[pos_]))) {
      return false;
    }

    if (std::isdigit(static_cast<unsigned char>(str_[pos_]))) {
      *out = str_[pos_] - '0';
    } else if (std::islower(static_cast<unsigned char>(str_[pos_]))) {
      *out = 10 + (str_[pos_] - 'a');
    } else {
      // Uppercase hexadecimal is not permitted.
      return false;
    }

    ++pos_;

    return true;
  }

  // Matches a decimal byte of at most 3 digits. The match will succeed even
  // if the decimal byte is followed immediately by a digit. If matching three
  // digits would produce a value greater than 255, only two digits are matched.
  bool MatchMax3DigitDecByte(uint8_t* byte_out) {
    FX_DCHECK(byte_out);

    uint8_t digit = 0;
    if (!MatchDecDigit(&digit)) {
      return false;
    }

    uint16_t accum = digit;
    if (MatchDecDigit(&digit)) {
      accum = accum * 10 + digit;
      if (accum <= 25 && MatchDecDigit(&digit)) {
        if (accum < 25 || digit < 6) {
          accum = accum * 10 + digit;
        } else {
          // Including that last digit would produce a value > 255.
          --pos_;
        }
      }
    }

    FX_DCHECK(accum <= 255);
    *byte_out = static_cast<uint8_t>(accum);
    return true;
  }

  // Matches a lowercase hexadecimal word of at most 4 digits. The match will
  // succeed even if the hexadecimal word is followed immediately by a
  // hexadecimal digit.
  bool MatchMax4DigitLowerHexWord(uint16_t* word_out) {
    FX_DCHECK(word_out);

    uint8_t digit = 0;
    if (!MatchLowerHexDigit(&digit)) {
      return false;
    }

    uint16_t accum = digit;
    if (MatchLowerHexDigit(&digit)) {
      accum = accum * 16 + digit;
      if (MatchLowerHexDigit(&digit)) {
        accum = accum * 16 + digit;
        if (MatchLowerHexDigit(&digit)) {
          accum = accum * 16 + digit;
        }
      }
    }

    *word_out = accum;
    return true;
  }

  // Matches an IPV4 address.
  bool MatchIpV4Address(IpAddress* address_out) {
    FX_DCHECK(address_out);

    size_t old_pos = pos_;
    uint8_t b0, b1, b2, b3;
    if (MatchMax3DigitDecByte(&b0) && Match('.') && MatchMax3DigitDecByte(&b1) && Match('.') &&
        MatchMax3DigitDecByte(&b2) && Match('.') && MatchMax3DigitDecByte(&b3)) {
      *address_out = IpAddress(b0, b1, b2, b3);
      return true;
    }

    pos_ = old_pos;
    return false;
  }

  // Matches an IPV6 address.
  bool MatchIpV6Address(IpAddress* address_out) {
    FX_DCHECK(address_out);

    size_t old_pos = pos_;
    uint16_t words[8];
    size_t word_index = 0;
    ssize_t ellipsis_word_index = -1;

    if (Match(':')) {
      ellipsis_word_index = 0;
      words[0] = 0;
    } else if (!MatchMax4DigitLowerHexWord(&words[word_index])) {
      pos_ = old_pos;
      return false;
    }

    if (Match(':')) {
      while (true) {
        // At this point, we've matched at least one word, we've just matched a
        // colon, and |word_index| indexes the last word we matched.
        ++word_index;

        // Check for "::" ellipsis.
        if (Match(':')) {
          if (ellipsis_word_index != -1) {
            // More than one "::" ellipsis.
            break;
          }

          ellipsis_word_index = word_index;
        }

        if (MatchMax4DigitLowerHexWord(&words[word_index])) {
          if (word_index < 7 && Match(':')) {
            // More words to read.
            continue;
          }
        } else {
          // We didn't match that last word.
          --word_index;
          if (word_index == 0) {
            if (ellipsis_word_index != 1) {
              // Need at least two words, if we don't have a trailing pair of colons.
              break;
            }
          } else {
            // We've read a ':' past the end.
            --pos_;
          }
        }

        if (word_index == 7) {
          if (ellipsis_word_index != -1) {
            // We parsed 8 words, and there's an ellipsis.
            break;
          }
        } else {
          if (ellipsis_word_index == -1) {
            // We parsed less than 8 words, and there's no ellipsis.
            break;
          }

          // Insert zeros for the ellipsis.
          ssize_t to = 7;
          for (ssize_t from = word_index; from >= ellipsis_word_index; --from) {
            words[to] = words[from];
            --to;
          }

          for (; to >= ellipsis_word_index; --to) {
            words[to] = 0;
          }
        }

        *address_out = IpAddress(words[0], words[1], words[2], words[3], words[4], words[5],
                                 words[6], words[7]);
        return true;
      }
    }

    pos_ = old_pos;
    return false;
  }

 private:
  const std::string& str_;
  size_t pos_;
};

}  // namespace

// static
const IpAddress IpAddress::kInvalid;
// static
const IpAddress IpAddress::kV4Loopback(127, 0, 0, 1);
// static
const IpAddress IpAddress::kV6Loopback(0, 0, 0, 0, 0, 0, 0, 1);

// static
IpAddress IpAddress::FromString(const std::string address_string, sa_family_t family) {
  FX_DCHECK(family == AF_UNSPEC || family == AF_INET || family == AF_INET6);

  Parser parser(address_string);
  IpAddress address;
  if ((parser.MatchIpV4Address(&address) || parser.MatchIpV6Address(&address)) &&
      parser.MatchEnd()) {
    return address;
  }

  return kInvalid;
}

IpAddress::IpAddress() : family_(AF_UNSPEC) { std::memset(&v6_, 0, sizeof(v6_)); }

IpAddress::IpAddress(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3) : family_(AF_INET) {
  uint8_t* bytes = reinterpret_cast<uint8_t*>(&v4_.s_addr);
  bytes[0] = b0;
  bytes[1] = b1;
  bytes[2] = b2;
  bytes[3] = b3;
}

IpAddress::IpAddress(in_addr_t addr) : family_(AF_INET) { v4_.s_addr = addr; }

IpAddress::IpAddress(const in_addr& addr) : family_(AF_INET), v4_(addr) {}

IpAddress::IpAddress(uint16_t w0, uint16_t w1, uint16_t w2, uint16_t w3, uint16_t w4, uint16_t w5,
                     uint16_t w6, uint16_t w7)
    : family_(AF_INET6) {
  uint16_t* words = v6_.s6_addr16;
  words[0] = htobe16(w0);
  words[1] = htobe16(w1);
  words[2] = htobe16(w2);
  words[3] = htobe16(w3);
  words[4] = htobe16(w4);
  words[5] = htobe16(w5);
  words[6] = htobe16(w6);
  words[7] = htobe16(w7);
}

IpAddress::IpAddress(uint16_t w0, uint16_t w7) : family_(AF_INET6) {
  std::memset(&v6_, 0, sizeof(v6_));
  uint16_t* words = v6_.s6_addr16;
  words[0] = htobe16(w0);
  words[7] = htobe16(w7);
}

IpAddress::IpAddress(const in6_addr& addr) : family_(AF_INET6), v6_(addr) {}

IpAddress::IpAddress(const sockaddr& addr) {
  switch (addr.sa_family) {
    case AF_INET:
      family_ = AF_INET;
      v4_ = *reinterpret_cast<const in_addr*>(addr.sa_data);
      break;
    case AF_INET6:
      family_ = AF_INET6;
      v6_ = *reinterpret_cast<const in6_addr*>(addr.sa_data);
      break;
    default:
      family_ = AF_UNSPEC;
      std::memset(&v6_, 0, sizeof(v6_));
      break;
  }
}

IpAddress::IpAddress(const sockaddr_storage& addr) {
  switch (addr.ss_family) {
    case AF_INET:
      family_ = AF_INET;
      v4_ = *reinterpret_cast<const in_addr*>(reinterpret_cast<const uint8_t*>(&addr) +
                                              sizeof(sa_family_t));
      break;
    case AF_INET6:
      family_ = AF_INET6;
      v6_ = *reinterpret_cast<const in6_addr*>(reinterpret_cast<const uint8_t*>(&addr) +
                                               sizeof(sa_family_t));
      break;
    default:
      family_ = AF_UNSPEC;
      std::memset(&v6_, 0, sizeof(v6_));
      break;
  }
}

IpAddress::IpAddress(const fuchsia::net::Ipv4Address& addr) : family_(AF_INET) {
  std::copy(addr.addr.cbegin(), addr.addr.cend(), reinterpret_cast<uint8_t*>(&v4_));
}

IpAddress::IpAddress(const fuchsia::net::Ipv6Address& addr) : family_(AF_INET6) {
  std::copy(addr.addr.cbegin(), addr.addr.cend(), reinterpret_cast<uint8_t*>(&v6_));
}

IpAddress::IpAddress(const fuchsia::net::IpAddress& addr) {
  switch (addr.Which()) {
    case fuchsia::net::IpAddress::Tag::kIpv4:
      family_ = AF_INET;
      std::copy(addr.ipv4().addr.cbegin(), addr.ipv4().addr.cend(),
                reinterpret_cast<uint8_t*>(&v4_));
      break;
    case fuchsia::net::IpAddress::Tag::kIpv6:
      family_ = AF_INET6;
      std::copy(addr.ipv6().addr.cbegin(), addr.ipv6().addr.cend(),
                reinterpret_cast<uint8_t*>(&v6_));
      break;
    case fuchsia::net::IpAddress::Tag::Invalid:
      FX_DCHECK(false);
      break;
  }
}

bool IpAddress::is_mapped_from_v4() const { return is_v6() && IN6_IS_ADDR_V4MAPPED(&v6_); }

IpAddress IpAddress::mapped_v4_address() const {
  FX_DCHECK(is_mapped_from_v4());
  auto bytes = as_bytes();
  return IpAddress(bytes[12], bytes[13], bytes[14], bytes[15]);
}

IpAddress IpAddress::mapped_as_v6() const {
  FX_DCHECK(is_v4());
  auto bytes = as_bytes();
  // The words passed in to this constructor are stored in big-endian order.
  return IpAddress(0, 0, 0, 0, 0, 0xffff, static_cast<uint16_t>(bytes[0] << 8) | bytes[1],
                   static_cast<uint16_t>(bytes[2] << 8) | bytes[3]);
}

bool IpAddress::is_loopback() const {
  switch (family_) {
    case AF_INET:
      return *this == kV4Loopback;
    case AF_INET6:
      return *this == kV6Loopback;
    default:
      return false;
  }
}

std::string IpAddress::ToString() const {
  std::ostringstream os;
  os << *this;
  return os.str();
}

std::ostream& operator<<(std::ostream& os, const IpAddress& value) {
  if (!value.is_valid()) {
    return os << "<invalid>";
  }

  if (value.is_v4()) {
    const uint8_t* bytes = value.as_bytes();
    return os << static_cast<int>(bytes[0]) << '.' << static_cast<int>(bytes[1]) << '.'
              << static_cast<int>(bytes[2]) << '.' << static_cast<int>(bytes[3]);
  } else {
    // IPV6 text representation per RFC 5952:
    // 1) Suppress leading zeros in hex representation of words.
    // 2) Don't use '::' to shorten a just single zero word.
    // 3) Shorten the longest sequence of zero words preferring the leftmost
    //    sequence if there's a tie.
    // 4) Use lower-case hexadecimal.

    const uint16_t* words = value.as_words();

    // Figure out where the longest span of zeros is.
    uint8_t start_of_zeros;
    uint8_t zeros_seen = 0;
    uint8_t start_of_best_zeros = 255;
    // Don't bother if the longest sequence is length 1.
    uint8_t best_zeros_seen = 1;

    for (uint8_t i = 0; i < 8; ++i) {
      if (words[i] == 0) {
        if (zeros_seen == 0) {
          start_of_zeros = i;
        }
        ++zeros_seen;
      } else if (zeros_seen != 0) {
        if (zeros_seen > best_zeros_seen) {
          start_of_best_zeros = start_of_zeros;
          best_zeros_seen = zeros_seen;
        }
        zeros_seen = 0;
      }
    }

    if (zeros_seen > best_zeros_seen) {
      start_of_best_zeros = start_of_zeros;
      best_zeros_seen = zeros_seen;
    }

    os << std::hex;
    for (uint8_t i = 0; i < 8; ++i) {
      if (i < start_of_best_zeros || i >= start_of_best_zeros + best_zeros_seen) {
        os << be16toh(words[i]);
        if (i != 7) {
          os << ":";
        }
      } else if (i == start_of_best_zeros) {
        if (i == 0) {
          os << "::";
        } else {
          os << ":";  // We just wrote a ':', so we only need one more.
        }
      }
    }
    return os << std::dec;
  }
}

}  // namespace inet
