/*
  chronyd/chronyc - Programs for keeping computer clocks accurate.

 **********************************************************************
 * Copyright (C) Richard P. Curnow  1997-2003
 * Copyright (C) Miroslav Lichvar  2009-2011
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 * 
 **********************************************************************

  =======================================================================

  Functions to do name to IP address conversion

  */

#include "config.h"

#include "sysincl.h"

#include "nameserv.h"
#include "util.h"

/* ================================================== */

static int address_family = IPADDR_UNSPEC;

void
DNS_SetAddressFamily(int family)
{
  address_family = family;
}

DNS_Status 
DNS_Name2IPAddress(const char *name, IPAddr *ip_addrs, int max_addrs)
{
#ifdef HAVE_GETADDRINFO
  struct addrinfo hints, *res, *ai;
  int i, result;

  max_addrs = MIN(max_addrs, DNS_MAX_ADDRESSES);

  memset(&hints, 0, sizeof (hints));

  switch (address_family) {
    case IPADDR_INET4:
      hints.ai_family = AF_INET;
      break;
#ifdef FEAT_IPV6
    case IPADDR_INET6:
      hints.ai_family = AF_INET6;
      break;
#endif
    default:
      hints.ai_family = AF_UNSPEC;
  }
  hints.ai_socktype = SOCK_STREAM;

  result = getaddrinfo(name, NULL, &hints, &res);

  if (result) {
#ifdef FORCE_DNSRETRY
    return DNS_TryAgain;
#else
    return result == EAI_AGAIN ? DNS_TryAgain : DNS_Failure;
#endif
  }

  for (ai = res, i = 0; i < max_addrs && ai != NULL; ai = ai->ai_next) {
    switch (ai->ai_family) {
      case AF_INET:
        if (address_family != IPADDR_UNSPEC && address_family != IPADDR_INET4)
          continue;
        ip_addrs[i].family = IPADDR_INET4;
        ip_addrs[i].addr.in4 = ntohl(((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr);
        i++;
        break;
#ifdef FEAT_IPV6
      case AF_INET6:
        if (address_family != IPADDR_UNSPEC && address_family != IPADDR_INET6)
          continue;
        ip_addrs[i].family = IPADDR_INET6;
        memcpy(&ip_addrs[i].addr.in6, &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr.s6_addr,
               sizeof (ip_addrs->addr.in6));
        i++;
        break;
#endif
    }
  }

  for (; i < max_addrs; i++)
        ip_addrs[i].family = IPADDR_UNSPEC;

  freeaddrinfo(res);

  return !max_addrs || ip_addrs[0].family != IPADDR_UNSPEC ? DNS_Success : DNS_Failure;
#else
  struct hostent *host;
  int i;
  
  if (address_family != IPADDR_UNSPEC && address_family != IPADDR_INET4)
    return DNS_Failure;

  max_addrs = MIN(max_addrs, DNS_MAX_ADDRESSES);

  host = gethostbyname(name);

  if (host == NULL) {
    if (h_errno == TRY_AGAIN)
      return DNS_TryAgain;
  } else {
    if (host->h_addrtype != AF_INET || !host->h_addr_list[0])
      return DNS_Failure;

    for (i = 0; host->h_addr_list[i] && i < max_addrs; i++) {
      ip_addrs[i].family = IPADDR_INET4;
      ip_addrs[i].addr.in4 = ntohl(*(uint32_t *)host->h_addr_list[i]);
    }

    for (; i < max_addrs; i++)
      ip_addrs[i].family = IPADDR_UNSPEC;

    return DNS_Success;
  }

#ifdef FORCE_DNSRETRY
  return DNS_TryAgain;
#else
  return DNS_Failure;
#endif

#endif
}

/* ================================================== */

int
DNS_IPAddress2Name(IPAddr *ip_addr, char *name, int len)
{
  char *result = NULL;

#ifdef FEAT_IPV6
  struct sockaddr_in6 in6;
  socklen_t slen;
  char hbuf[NI_MAXHOST];

  slen = UTI_IPAndPortToSockaddr(ip_addr, 0, (struct sockaddr *)&in6);
  if (!getnameinfo((struct sockaddr *)&in6, slen, hbuf, sizeof (hbuf), NULL, 0, 0))
    result = hbuf;
#else
  struct hostent *host;
  uint32_t addr;

  switch (ip_addr->family) {
    case IPADDR_INET4:
      addr = htonl(ip_addr->addr.in4);
      host = gethostbyaddr((const char *) &addr, sizeof (ip_addr), AF_INET);
      break;
#ifdef FEAT_IPV6
    case IPADDR_INET6:
      host = gethostbyaddr((const void *) ip_addr->addr.in6, sizeof (ip_addr->addr.in6), AF_INET6);
      break;
#endif
    default:
      host = NULL;
  }
  if (host)
    result = host->h_name;
#endif

  if (result == NULL)
    result = UTI_IPToString(ip_addr);
  if (snprintf(name, len, "%s", result) >= len)
    return 0;

  return 1;
}

/* ================================================== */

void
DNS_Reload(void)
{
  res_init();
}

/* ================================================== */

