/* Copyright (C) 1996, 1997, 1998, 1999, 2002, 2004, 2007, 2008
   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, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

/* 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 "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;
  char *qbuf;
  enum nss_status status;

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

  qbuf = strdupa (name);

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

  anslen = __libc_res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
			       1024, &net_buffer.ptr, 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);
  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;
  char *ans;
  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;
  ans = NULL;

  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;
      ans = strdupa (bp);
      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 = result->n_aliases++;
	    while (*ap != NULL)
	      {
		/* 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;
}
