
/* Copyright 1998 by the Massachusetts Institute of Technology.
 *
 * Permission to use, copy, modify, and distribute this
 * software and its documentation for any purpose and without
 * fee is hereby granted, provided that the above copyright
 * notice appear in all copies and that both that copyright
 * notice and this permission notice appear in supporting
 * documentation, and that the name of M.I.T. not be used in
 * advertising or publicity pertaining to distribution of the
 * software without specific, written prior permission.
 * M.I.T. makes no representations about the suitability of
 * this software for any purpose.  It is provided "as is"
 * without express or implied warranty.
 */

#include "ares_setup.h"

#ifdef HAVE_SYS_SOCKET_H
#  include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#  include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_NAMESER_H
#  include <arpa/nameser.h>
#else
#  include "nameser.h"
#endif
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
#  include <arpa/nameser_compat.h>
#endif

#include <stdlib.h>
#include "ares.h"
#include "ares_private.h" /* for the memdebug */

static int name_length(const unsigned char *encoded, const unsigned char *abuf,
                       int alen);

/* Expand an RFC1035-encoded domain name given by encoded.  The
 * containing message is given by abuf and alen.  The result given by
 * *s, which is set to a NUL-terminated allocated buffer.  *enclen is
 * set to the length of the encoded name (not the length of the
 * expanded name; the goal is to tell the caller how many bytes to
 * move forward to get past the encoded name).
 *
 * In the simple case, an encoded name is a series of labels, each
 * composed of a one-byte length (limited to values between 0 and 63
 * inclusive) followed by the label contents.  The name is terminated
 * by a zero-length label.
 *
 * In the more complicated case, a label may be terminated by an
 * indirection pointer, specified by two bytes with the high bits of
 * the first byte (corresponding to INDIR_MASK) set to 11.  With the
 * two high bits of the first byte stripped off, the indirection
 * pointer gives an offset from the beginning of the containing
 * message with more labels to decode.  Indirection can happen an
 * arbitrary number of times, so we have to detect loops.
 *
 * Since the expanded name uses '.' as a label separator, we use
 * backslashes to escape periods or backslashes in the expanded name.
 */

int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
                     int alen, char **s, long *enclen)
{
  int len, indir = 0;
  char *q;
  const unsigned char *p;
  union {
    ssize_t sig;
     size_t uns;
  } nlen;

  nlen.sig = name_length(encoded, abuf, alen);
  if (nlen.sig < 0)
    return ARES_EBADNAME;

  *s = malloc(nlen.uns + 1);
  if (!*s)
    return ARES_ENOMEM;
  q = *s;

  if (nlen.uns == 0) {
    /* RFC2181 says this should be ".": the root of the DNS tree.
     * Since this function strips trailing dots though, it becomes ""
     */
    q[0] = '\0';

    /* indirect root label (like 0xc0 0x0c) is 2 bytes long (stupid, but
       valid) */
    if ((*encoded & INDIR_MASK) == INDIR_MASK)
      *enclen = 2;
    else
      *enclen = 1;  /* the caller should move one byte to get past this */

    return ARES_SUCCESS;
  }

  /* No error-checking necessary; it was all done by name_length(). */
  p = encoded;
  while (*p)
    {
      if ((*p & INDIR_MASK) == INDIR_MASK)
        {
          if (!indir)
            {
              *enclen = p + 2 - encoded;
              indir = 1;
            }
          p = abuf + ((*p & ~INDIR_MASK) << 8 | *(p + 1));
        }
      else
        {
          len = *p;
          p++;
          while (len--)
            {
              if (*p == '.' || *p == '\\')
                *q++ = '\\';
              *q++ = *p;
              p++;
            }
          *q++ = '.';
        }
    }
  if (!indir)
    *enclen = p + 1 - encoded;

  /* Nuke the trailing period if we wrote one. */
  if (q > *s)
    *(q - 1) = 0;
  else
    *q = 0; /* zero terminate */

  return ARES_SUCCESS;
}

/* Return the length of the expansion of an encoded domain name, or
 * -1 if the encoding is invalid.
 */
static int name_length(const unsigned char *encoded, const unsigned char *abuf,
                       int alen)
{
  int n = 0, offset, indir = 0;

  /* Allow the caller to pass us abuf + alen and have us check for it. */
  if (encoded == abuf + alen)
    return -1;

  while (*encoded)
    {
      if ((*encoded & INDIR_MASK) == INDIR_MASK)
        {
          /* Check the offset and go there. */
          if (encoded + 1 >= abuf + alen)
            return -1;
          offset = (*encoded & ~INDIR_MASK) << 8 | *(encoded + 1);
          if (offset >= alen)
            return -1;
          encoded = abuf + offset;

          /* If we've seen more indirects than the message length,
           * then there's a loop.
           */
          if (++indir > alen)
            return -1;
        }
      else
        {
          offset = *encoded;
          if (encoded + offset + 1 >= abuf + alen)
            return -1;
          encoded++;
          while (offset--)
            {
              n += (*encoded == '.' || *encoded == '\\') ? 2 : 1;
              encoded++;
            }
          n++;
        }
    }

  /* If there were any labels at all, then the number of dots is one
   * less than the number of labels, so subtract one.
   */
  return (n) ? n - 1 : n;
}

/* Like ares_expand_name but returns EBADRESP in case of invalid input. */
int ares__expand_name_for_response(const unsigned char *encoded,
                                   const unsigned char *abuf, int alen,
                                   char **s, long *enclen)
{
  int status = ares_expand_name(encoded, abuf, alen, s, enclen);
  if (status == ARES_EBADNAME)
    status = ARES_EBADRESP;
  return status;
}
