/* Copyright (C) 1996-2014 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Extended from original form by Ulrich Drepper <drepper@cygnus.com>, 1996.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

/* Parts of this file are plain copies of the file `getnetnamadr.c' from
   the bind package and it has the following copyright.  */

/* Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
 *      Dep. Matematica Universidade de Coimbra, Portugal, Europe
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 */
/*
 * Copyright (c) 1983, 1993
 *      The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

#include "nsswitch.h"
#include <arpa/inet.h>

/* Maximum number of aliases we allow.  */
#define MAX_NR_ALIASES	48


#if PACKETSZ > 65536
# define MAXPACKET	PACKETSZ
#else
# define MAXPACKET	65536
#endif


typedef enum
{
  BYADDR,
  BYNAME
} lookup_method;


/* We need this time later.  */
typedef union querybuf
{
  HEADER hdr;
  u_char buf[MAXPACKET];
} querybuf;

/* These functions are defined in res_comp.c.  */
#define NS_MAXCDNAME	255	/* maximum compressed domain name */
extern int __ns_name_ntop (const u_char *, char *, size_t) __THROW;
extern int __ns_name_unpack (const u_char *, const u_char *,
			     const u_char *, u_char *, size_t) __THROW;


/* Prototypes for local functions.  */
static enum nss_status getanswer_r (const querybuf *answer, int anslen,
				    struct netent *result, char *buffer,
				    size_t buflen, int *errnop, int *h_errnop,
				    lookup_method net_i);


enum nss_status
_nss_dns_getnetbyname_r (const char *name, struct netent *result,
			 char *buffer, size_t buflen, int *errnop,
			 int *herrnop)
{
  /* Return entry for network with NAME.  */
  union
  {
    querybuf *buf;
    u_char *ptr;
  } net_buffer;
  querybuf *orig_net_buffer;
  int anslen;
  enum nss_status status;

  if (__res_maybe_init (&_res, 0) == -1)
    return NSS_STATUS_UNAVAIL;

  net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);

  anslen = __libc_res_nsearch (&_res, name, C_IN, T_PTR, net_buffer.buf->buf,
			       1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
  if (anslen < 0)
    {
      /* Nothing found.  */
      *errnop = errno;
      if (net_buffer.buf != orig_net_buffer)
	free (net_buffer.buf);
      return (errno == ECONNREFUSED
	      || errno == EPFNOSUPPORT
	      || errno == EAFNOSUPPORT)
	? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND;
    }

  status = getanswer_r (net_buffer.buf, anslen, result, buffer, buflen,
			errnop, herrnop, BYNAME);
  if (net_buffer.buf != orig_net_buffer)
    free (net_buffer.buf);
  return status;
}


enum nss_status
_nss_dns_getnetbyaddr_r (uint32_t net, int type, struct netent *result,
			 char *buffer, size_t buflen, int *errnop,
			 int *herrnop)
{
  /* Return entry for network with NAME.  */
  enum nss_status status;
  union
  {
    querybuf *buf;
    u_char *ptr;
  } net_buffer;
  querybuf *orig_net_buffer;
  unsigned int net_bytes[4];
  char qbuf[MAXDNAME];
  int cnt, anslen;
  u_int32_t net2;
  int olderr = errno;

  /* No net address lookup for IPv6 yet.  */
  if (type != AF_INET)
    return NSS_STATUS_UNAVAIL;

  if (__res_maybe_init (&_res, 0) == -1)
    return NSS_STATUS_UNAVAIL;

  net2 = (u_int32_t) net;
  for (cnt = 4; net2 != 0; net2 >>= 8)
    net_bytes[--cnt] = net2 & 0xff;

  switch (cnt)
    {
    case 3:
      /* Class A network.  */
      sprintf (qbuf, "0.0.0.%u.in-addr.arpa", net_bytes[3]);
      break;
    case 2:
      /* Class B network.  */
      sprintf (qbuf, "0.0.%u.%u.in-addr.arpa", net_bytes[3], net_bytes[2]);
      break;
    case 1:
      /* Class C network.  */
      sprintf (qbuf, "0.%u.%u.%u.in-addr.arpa", net_bytes[3], net_bytes[2],
	       net_bytes[1]);
      break;
    case 0:
      /* Class D - E network.  */
      sprintf (qbuf, "%u.%u.%u.%u.in-addr.arpa", net_bytes[3], net_bytes[2],
	       net_bytes[1], net_bytes[0]);
      break;
    }

  net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);

  anslen = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
			      1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
  if (anslen < 0)
    {
      /* Nothing found.  */
      int err = errno;
      __set_errno (olderr);
      if (net_buffer.buf != orig_net_buffer)
	free (net_buffer.buf);
      return (err == ECONNREFUSED
	      || err == EPFNOSUPPORT
	      || err == EAFNOSUPPORT)
	? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND;
    }

  status = getanswer_r (net_buffer.buf, anslen, result, buffer, buflen,
			errnop, herrnop, BYADDR);
  if (net_buffer.buf != orig_net_buffer)
    free (net_buffer.buf);
  if (status == NSS_STATUS_SUCCESS)
    {
      /* Strip trailing zeros.  */
      unsigned int u_net = net;	/* Maybe net should be unsigned?  */

      while ((u_net & 0xff) == 0 && u_net != 0)
	u_net >>= 8;
      result->n_net = u_net;
    }

  return status;
}


#undef offsetof
#define offsetof(Type, Member) ((size_t) &((Type *) NULL)->Member)

static enum nss_status
getanswer_r (const querybuf *answer, int anslen, struct netent *result,
	     char *buffer, size_t buflen, int *errnop, int *h_errnop,
	     lookup_method net_i)
{
  /*
   * Find first satisfactory answer
   *
   *      answer --> +------------+  ( MESSAGE )
   *                 |   Header   |
   *                 +------------+
   *                 |  Question  | the question for the name server
   *                 +------------+
   *                 |   Answer   | RRs answering the question
   *                 +------------+
   *                 | Authority  | RRs pointing toward an authority
   *                 | Additional | RRs holding additional information
   *                 +------------+
   */
  struct net_data
  {
    char *aliases[MAX_NR_ALIASES];
    char linebuffer[0];
  } *net_data;

  uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct net_data);
  buffer += pad;

  if (__builtin_expect (buflen < sizeof (*net_data) + pad, 0))
    {
      /* The buffer is too small.  */
    too_small:
      *errnop = ERANGE;
      *h_errnop = NETDB_INTERNAL;
      return NSS_STATUS_TRYAGAIN;
    }
  buflen -= pad;

  net_data = (struct net_data *) buffer;
  int linebuflen = buflen - offsetof (struct net_data, linebuffer);
  if (buflen - offsetof (struct net_data, linebuffer) != linebuflen)
    linebuflen = INT_MAX;
  const unsigned char *end_of_message = &answer->buf[anslen];
  const HEADER *header_pointer = &answer->hdr;
  /* #/records in the answer section.  */
  int answer_count =  ntohs (header_pointer->ancount);
  /* #/entries in the question section.  */
  int question_count = ntohs (header_pointer->qdcount);
  char *bp = net_data->linebuffer;
  const unsigned char *cp = &answer->buf[HFIXEDSZ];
  char **alias_pointer;
  int have_answer;
  u_char packtmp[NS_MAXCDNAME];

  if (question_count == 0)
    {
      /* FIXME: the Sun version uses for host name lookup an additional
	 parameter for pointing to h_errno.  this is missing here.
	 OSF/1 has a per-thread h_errno variable.  */
      if (header_pointer->aa != 0)
	{
	  __set_h_errno (HOST_NOT_FOUND);
	  return NSS_STATUS_NOTFOUND;
	}
      else
	{
	  __set_h_errno (TRY_AGAIN);
	  return NSS_STATUS_TRYAGAIN;
	}
    }

  /* Skip the question part.  */
  while (question_count-- > 0)
    {
      int n = __dn_skipname (cp, end_of_message);
      if (n < 0 || end_of_message - (cp + n) < QFIXEDSZ)
       {
         __set_h_errno (NO_RECOVERY);
         return NSS_STATUS_UNAVAIL;
       }
      cp += n + QFIXEDSZ;
    }

  alias_pointer = result->n_aliases = &net_data->aliases[0];
  *alias_pointer = NULL;
  have_answer = 0;

  while (--answer_count >= 0 && cp < end_of_message)
    {
      int n = dn_expand (answer->buf, end_of_message, cp, bp, linebuflen);
      int type, class;

      n = __ns_name_unpack (answer->buf, end_of_message, cp,
			    packtmp, sizeof packtmp);
      if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1)
	{
	  if (errno == EMSGSIZE)
	    goto too_small;

	  n = -1;
	}

      if (n > 0 && bp[0] == '.')
	bp[0] = '\0';

      if (n < 0 || res_dnok (bp) == 0)
	break;
      cp += n;
      GETSHORT (type, cp);
      GETSHORT (class, cp);
      cp += INT32SZ;		/* TTL */
      GETSHORT (n, cp);

      if (class == C_IN && type == T_PTR)
	{
	  n = __ns_name_unpack (answer->buf, end_of_message, cp,
				packtmp, sizeof packtmp);
	  if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1)
	    {
	      if (errno == EMSGSIZE)
		goto too_small;

	      n = -1;
	    }

	  if (n < 0 || !res_hnok (bp))
	    {
	      /* XXX What does this mean?  The original form from bind
		 returns NULL. Incrementing cp has no effect in any case.
		 What should I return here. ??? */
	      cp += n;
	      return NSS_STATUS_UNAVAIL;
	    }
	  cp += n;
         if (alias_pointer + 2 < &net_data->aliases[MAX_NR_ALIASES])
           {
             *alias_pointer++ = bp;
             n = strlen (bp) + 1;
             bp += n;
             linebuflen -= n;
             result->n_addrtype = class == C_IN ? AF_INET : AF_UNSPEC;
             ++have_answer;
           }
	}
    }

  if (have_answer)
    {
      *alias_pointer = NULL;
      switch (net_i)
	{
	case BYADDR:
	  result->n_name = *result->n_aliases++;
	  result->n_net = 0L;
	  return NSS_STATUS_SUCCESS;

	case BYNAME:
	  {
	    char **ap;
	    for (ap = result->n_aliases; *ap != NULL; ++ap)
	      {
		/* Check each alias name for being of the forms:
		   4.3.2.1.in-addr.arpa		= net 1.2.3.4
		   3.2.1.in-addr.arpa		= net 0.1.2.3
		   2.1.in-addr.arpa		= net 0.0.1.2
		   1.in-addr.arpa		= net 0.0.0.1
		*/
		uint32_t val = 0;	/* Accumulator for n_net value.  */
		unsigned int shift = 0; /* Which part we are parsing now.  */
		const char *p = *ap; /* Consuming the string.  */
		do
		  {
		    /* Match the leading 0 or 0[xX] base indicator.  */
		    unsigned int base = 10;
		    if (*p == '0' && p[1] != '.')
		      {
			base = 8;
			++p;
			if (*p == 'x' || *p == 'X')
			  {
			    base = 16;
			    ++p;
			    if (*p == '.')
			      break; /* No digit here.  Give up on alias.  */
			  }
			if (*p == '\0')
			  break;
		      }

		    uint32_t part = 0; /* Accumulates this part's number.  */
		    do
		      {
			if (isdigit (*p) && (*p - '0' < base))
			  part = (part * base) + (*p - '0');
			else if (base == 16 && isxdigit (*p))
			  part = (part << 4) + 10 + (tolower (*p) - 'a');
			++p;
		      } while (*p != '\0' && *p != '.');

		    if (*p != '.')
		      break;	/* Bad form.  Give up on this name.  */

		    /* Install this as the next more significant byte.  */
		    val |= part << shift;
		    shift += 8;
		    ++p;

		    /* If we are out of digits now, there are two cases:
		       1. We are done with digits and now see "in-addr.arpa".
		       2. This is not the droid we are looking for.  */
		    if (!isdigit (*p) && !strcasecmp (p, "in-addr.arpa"))
		      {
			result->n_net = val;
			return NSS_STATUS_SUCCESS;
		      }

		    /* Keep going when we have seen fewer than 4 parts.  */
		  } while (shift < 32);
	      }
	  }
	  break;
	}
    }

  __set_h_errno (TRY_AGAIN);
  return NSS_STATUS_TRYAGAIN;
}
