// Copyright (c) 2011 The Chromium 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 "net/base/dns_util.h"

#include <cstring>

namespace net {

// Based on DJB's public domain code.
bool DNSDomainFromDot(const base::StringPiece& dotted, std::string* out) {
  const char* buf = dotted.data();
  unsigned n = dotted.size();
  char label[63];
  unsigned int labellen = 0; /* <= sizeof label */
  char name[255];
  unsigned int namelen = 0; /* <= sizeof name */
  char ch;

  for (;;) {
    if (!n)
      break;
    ch = *buf++;
    --n;
    if (ch == '.') {
      if (labellen) {
        if (namelen + labellen + 1 > sizeof name)
          return false;
        name[namelen++] = labellen;
        memcpy(name + namelen, label, labellen);
        namelen += labellen;
        labellen = 0;
      }
      continue;
    }
    if (labellen >= sizeof label)
      return false;
    label[labellen++] = ch;
  }

  if (labellen) {
    if (namelen + labellen + 1 > sizeof name)
      return false;
    name[namelen++] = labellen;
    memcpy(name + namelen, label, labellen);
    namelen += labellen;
    labellen = 0;
  }

  if (namelen + 1 > sizeof name)
    return false;
  name[namelen++] = 0;  // This is the root label (of length 0).

  *out = std::string(name, namelen);
  return true;
}

std::string DNSDomainToString(const base::StringPiece& domain) {
  std::string ret;

  for (unsigned i = 0; i < domain.size() && domain[i]; i += domain[i] + 1) {
#if CHAR_MIN < 0
    if (domain[i] < 0)
      return "";
#endif
    if (domain[i] > 63)
      return "";

    if (i)
      ret += ".";

    if (static_cast<unsigned>(domain[i]) + i + 1 > domain.size())
      return "";

    domain.substr(i + 1, domain[i]).AppendToString(&ret);
  }
  return ret;
}

bool IsSTD3ASCIIValidCharacter(char c) {
  if (c <= 0x2c)
    return false;
  if (c >= 0x7b)
    return false;
  if (c >= 0x2e && c <= 0x2f)
    return false;
  if (c >= 0x3a && c <= 0x40)
    return false;
  if (c >= 0x5b && c <= 0x60)
    return false;
  return true;
}

std::string TrimEndingDot(const base::StringPiece& host) {
  base::StringPiece host_trimmed = host;
  size_t len = host_trimmed.length();
  if (len > 1 && host_trimmed[len - 1] == '.') {
    host_trimmed.remove_suffix(1);
  }
  return host_trimmed.as_string();
}

bool DnsResponseBuffer::U8(uint8* v) {
  if (len_ < 1)
    return false;
  *v = *p_;
  p_++;
  len_--;
  return true;
}

bool DnsResponseBuffer::U16(uint16* v) {
  if (len_ < 2)
    return false;
  *v = static_cast<uint16>(p_[0]) << 8 |
       static_cast<uint16>(p_[1]);
  p_ += 2;
  len_ -= 2;
  return true;
}

bool DnsResponseBuffer::U32(uint32* v) {
  if (len_ < 4)
    return false;
  *v = static_cast<uint32>(p_[0]) << 24 |
       static_cast<uint32>(p_[1]) << 16 |
       static_cast<uint32>(p_[2]) << 8 |
       static_cast<uint32>(p_[3]);
  p_ += 4;
  len_ -= 4;
  return true;
}

bool DnsResponseBuffer::Skip(unsigned n) {
  if (len_ < n)
    return false;
  p_ += n;
  len_ -= n;
  return true;
}

bool DnsResponseBuffer::Block(base::StringPiece* out, unsigned len) {
  if (len_ < len)
    return false;
  *out = base::StringPiece(reinterpret_cast<const char*>(p_), len);
  p_ += len;
  len_ -= len;
  return true;
}

// DNSName parses a (possibly compressed) DNS name from the packet. If |name|
// is not NULL, then the name is written into it. See RFC 1035 section 4.1.4.
bool DnsResponseBuffer::DNSName(std::string* name) {
  unsigned jumps = 0;
  const uint8* p = p_;
  unsigned len = len_;

  if (name)
    name->clear();

  for (;;) {
    if (len < 1)
      return false;
    uint8 d = *p;
    p++;
    len--;

    // The two couple of bits of the length give the type of the length. It's
    // either a direct length or a pointer to the remainder of the name.
    if ((d & 0xc0) == 0xc0) {
      // This limit matches the depth limit in djbdns.
      if (jumps > 100)
        return false;
      if (len < 1)
        return false;
      uint16 offset = static_cast<uint16>(d) << 8 |
                      static_cast<uint16>(p[0]);
      offset &= 0x3ff;
      p++;
      len--;

      if (jumps == 0) {
        p_ = p;
        len_ = len;
      }
      jumps++;

      if (offset >= packet_len_)
        return false;
      p = &packet_[offset];
      len = packet_len_ - offset;
    } else if ((d & 0xc0) == 0) {
      uint8 label_len = d;
      if (len < label_len)
        return false;
      if (name && label_len) {
        if (!name->empty())
          name->append(".");
        name->append(reinterpret_cast<const char*>(p), label_len);
      }
      p += label_len;
      len -= label_len;

      if (jumps == 0) {
        p_ = p;
        len_ = len;
      }

      if (label_len == 0)
        break;
    } else {
      return false;
    }
  }

  return true;
}

}  // namespace net
