/*
 * Copyright (c) 2001, 02  Motoyuki Kasahara
 *
 * 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.
 * 3. Neither the name of the project 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 PROJECT 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 PROJECT 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.
 */

/*
 * This program provides getaddrinfo() and getnameinfo() described in
 * RFC2133, 2553 and 3493.  These functions are mainly used for IPv6
 * application to resolve hostname or address.
 * 
 * This program is designed to be working on traditional IPv4 systems
 * which don't have those functions.  Therefore, this implementation
 * supports IPv4 only.
 *
 * This program is useful for application which should support both IPv6
 * and traditional IPv4 systems.  Use genuine getaddrinfo() and getnameinfo()
 * provided by system if the system supports IPv6.  Otherwise, use this
 * implementation.
 * 
 * This program is intended to be used in combination with GNU Autoconf.
 * 
 * This program also provides freeaddrinfo() and gai_strerror().
 *
 * To use this program in your application, insert the following lines to
 * C source files after including `sys/types.h', `sys/socket.h' and
 * `netdb.h'.  `getaddrinfo.h' defines `struct addrinfo' and AI_, NI_,
 * EAI_ macros.
 * 
 *    #ifndef HAVE_GETADDRINFO
 *    #include "getaddrinfo.h"
 *    #endif
 * 
 * Restriction:
 *   getaddrinfo() and getnameinfo() of this program are NOT thread
 *   safe, unless the cpp macro ENABLE_PTHREAD is defined.
 */

/*
 * Add the following code to your configure.ac (or configure.in).
 *   AC_C_CONST
 *   AC_HEADER_STDC
 *   AC_CHECK_HEADERS(string.h memory.h stdlib.h)
 *   AC_CHECK_FUNCS(memcpy)
 *   AC_REPLACE_FUNCS(memset)
 *   AC_TYPE_SOCKLEN_T
 *   AC_TYPE_IN_PORT_T
 *   AC_DECL_H_ERRNO
 *
 *   AC_CHECK_FUNCS(getaddrinfo getnameinfo)
 *   if test "$ac_cv_func_getaddrinfo$ac_cv_func_getnameinfo" != yesyes ; then
 *       LIBOBJS="$LIBOBJS getaddrinfo.$ac_objext"
 *   fi
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <sys/types.h>
#include <stdio.h>

#ifdef WIN32
#include <time.h>
#include <winsock2.h>
#ifdef DO_IPV6
#include <ws2tcpip.h>
#endif  /* DO_IPV6 */
#include <windows.h>
#else
#include <sys/socket.h>
#endif
 

#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
#include <string.h>
#if !defined(STDC_HEADERS) && defined(HAVE_MEMORY_H)
#include <memory.h>
#endif /* not STDC_HEADERS and HAVE_MEMORY_H */
#else /* not STDC_HEADERS and not HAVE_STRING_H */
#include <strings.h>
#endif /* not STDC_HEADERS and not HAVE_STRING_H */

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

#ifdef ENABLE_PTHREAD
#include <pthread.h>
#endif

#ifdef ENABLE_NLS
#include <libintl.h>
#endif

#ifndef HAVE_MEMCPY
#define memcpy(d, s, n) bcopy((s), (d), (n))
#ifdef __STDC__
void *memchr(const void *, int, size_t);
int memcmp(const void *, const void *, size_t);
void *memmove(void *, const void *, size_t);
void *memset(void *, int, size_t);
#else /* not __STDC__ */
char *memchr();
int memcmp();
char *memmove();
char *memset();
#endif /* not __STDC__ */
#endif /* not HAVE_MEMCPY */

#ifndef H_ERRNO_DECLARED
extern int h_errno;
#endif

#include "getaddrinfo.h"

#ifdef ENABLE_NLS
#define _(string) gettext(string)
#ifdef gettext_noop
#define N_(string) gettext_noop(string)
#else
#define N_(string) (string)
#endif
#else
#define gettext(string) (string)
#define _(string) (string)
#define N_(string) (string)
#endif

/*
 * Error messages for gai_strerror().
 */
static char *eai_errlist[] = {
    N_("Success"),

    /* EAI_ADDRFAMILY */
    N_("Address family for hostname not supported"),

    /* EAI_AGAIN */
    N_("Temporary failure in name resolution"),

    /* EAI_BADFLAGS */
    N_("Invalid value for ai_flags"),

    /* EAI_FAIL */
    N_("Non-recoverable failure in name resolution"),

    /* EAI_FAMILY */
    N_("ai_family not supported"),                      

    /* EAI_MEMORY */
    N_("Memory allocation failure"),

    /* EAI_NONAME */
    N_("hostname nor servname provided, or not known"),

    /* EAI_OVERFLOW */
    N_("An argument buffer overflowed"),

    /* EAI_SERVICE */
    N_("servname not supported for ai_socktype"),

    /* EAI_SOCKTYPE */
    N_("ai_socktype not supported"),

    /* EAI_SYSTEM */
    N_("System error returned in errno")
};

/*
 * Default hints for getaddrinfo().
 */
static struct addrinfo default_hints = {
    0, PF_UNSPEC, 0, 0, 0, NULL, NULL, NULL
};

/*
 * Mutex.
 */
#ifdef ENABLE_PTHREAD
static pthread_mutex_t gai_mutex = PTHREAD_MUTEX_INITIALIZER;
#endif

/*
 * Declaration of static functions.
 */
#ifdef __STDC__
static int is_integer(const char *);
static int is_address(const char *);
static int itoa_length(int);
#else
static int is_integer();
static int is_address();
static int itoa_length();
#endif

/*
 * gai_strerror().
 */
const char *
gai_strerror(ecode)
    int ecode;
{
    if (ecode < 0 || ecode > EAI_SYSTEM)
	return _("Unknown error");

    return gettext(eai_errlist[ecode]);
}

/*
 * freeaddrinfo().
 */
void
freeaddrinfo(ai)
    struct addrinfo *ai;
{
    struct addrinfo *next_ai;

    while (ai != NULL) {
	if (ai->ai_canonname != NULL)
	    free(ai->ai_canonname);
	if (ai->ai_addr != NULL)
	    free(ai->ai_addr);
	next_ai = ai->ai_next;
	free(ai);
	ai = next_ai;
    }
}

/*
 * Return 1 if the string `s' represents an integer.
 */
static int
is_integer(s)
    const char *s;
{
    if (*s == '-' || *s == '+')
	s++;
    if (*s < '0' || '9' < *s)
	return 0;

    s++;
    while ('0' <= *s && *s <= '9')
	s++;

    return (*s == '\0');
}

/*
 * Return 1 if the string `s' represents an IPv4 address.
 * Unlike inet_addr(), it doesn't permit malformed nortation such
 * as "192.168".
 */
static int
is_address(s)
    const char *s;
{
    const static char delimiters[] = {'.', '.', '.', '\0'};
    int i, j;
    int octet;

    for (i = 0; i < 4; i++) {
	if (*s == '0' && *(s + 1) != delimiters[i])
	    return 0;
	for (j = 0, octet = 0; '0' <= *s && *s <= '9' && j < 3; s++, j++)
	    octet = octet * 10 + (*s - '0');
	if (j == 0 || octet > 255 || *s != delimiters[i])
	    return 0;
	s++;
    }

    return 1;
}

/*
 * Calcurate length of the string `s', where `s' is set by
 * sprintf(s, "%d", n).
 */
static int
itoa_length(n)
    int n;
{
    int result = 1;

    if (n < 0) {
	n = -n;
	result++;
    }

    while (n >= 10) {
	result++;
	n /= 10;
    }

    return result;
}

/*
 * getaddrinfo().
 */
int
getaddrinfo(nodename, servname, hints, res)
    const char *nodename;
    const char *servname;
    const struct addrinfo *hints;
    struct addrinfo **res;
{
    struct addrinfo *head_res = NULL;
    struct addrinfo *tail_res = NULL;
    struct addrinfo *new_res;
    struct sockaddr_in *sa_in;
    struct in_addr **addr_list;
    struct in_addr *addr_list_buf[2];
    struct in_addr addr_buf;
    struct in_addr **ap;
    struct servent *servent;
    struct hostent *hostent;
    const char *canonname = NULL;
    in_port_t port;
    int saved_h_errno;
    int result = 0;

#ifdef ENABLE_PTHREAD
    pthread_mutex_lock(&gai_mutex);
#endif

    saved_h_errno = h_errno;

    if (nodename == NULL && servname == NULL) {
	result = EAI_NONAME;
	goto end;
    }

    if (hints != NULL) {
	if (hints->ai_family != PF_INET && hints->ai_family != PF_UNSPEC) {
	    result = EAI_FAMILY;
	    goto end;
	}
	if (hints->ai_socktype != SOCK_DGRAM
	    && hints->ai_socktype != SOCK_STREAM
	    && hints->ai_socktype != 0) {
	    result = EAI_SOCKTYPE;
	    goto end;
	}
    } else {
	hints = &default_hints;
    }

    if (servname != NULL) {
	if (is_integer(servname))
	    port = htons(atoi(servname));
	else  {
	    if (hints->ai_flags & AI_NUMERICSERV) {
		result = EAI_NONAME;
		goto end;
	    }

	    if (hints->ai_socktype == SOCK_DGRAM)
		servent = getservbyname(servname, "udp");
	    else if (hints->ai_socktype == SOCK_STREAM)
		servent = getservbyname(servname, "tcp");
	    else if (hints->ai_socktype == 0)
		servent = getservbyname(servname, "tcp");
	    else {
		result = EAI_SOCKTYPE;
		goto end;
	    }

	    if (servent == NULL) {
		result = EAI_SERVICE;
		goto end;
	    }
	    port = servent->s_port;
	}
    } else {
	port = htons(0);
    }

    if (nodename != NULL) {
	if (is_address(nodename)) {
	    addr_buf.s_addr = inet_addr(nodename);
	    addr_list_buf[0] = &addr_buf;
	    addr_list_buf[1] = NULL;
	    addr_list = addr_list_buf;

	    if (hints->ai_flags & AI_CANONNAME
		&& !(hints->ai_flags & AI_NUMERICHOST)) {
		hostent = gethostbyaddr((char *)&addr_buf,
		    sizeof(struct in_addr), AF_INET);
		if (hostent != NULL)
		    canonname = hostent->h_name;
		else
		    canonname = nodename;
	    }
	} else {
	    if (hints->ai_flags & AI_NUMERICHOST) {
		result = EAI_NONAME;
		goto end;
	    }

	    hostent = gethostbyname(nodename);
	    if (hostent == NULL) {
		switch (h_errno) {
		case HOST_NOT_FOUND:
		case NO_DATA:
		    result = EAI_NONAME;
		    goto end;
		case TRY_AGAIN:
		    result = EAI_AGAIN;
		    goto end;
		default:
		    result = EAI_FAIL;
		    goto end;
                }
	    }
	    addr_list = (struct in_addr **)hostent->h_addr_list;

	    if (hints->ai_flags & AI_CANONNAME)
		canonname = hostent->h_name;
	}
    } else {
	if (hints->ai_flags & AI_PASSIVE)
	    addr_buf.s_addr = htonl(INADDR_ANY);
	else
	    addr_buf.s_addr = htonl(0x7F000001);
	addr_list_buf[0] = &addr_buf;
	addr_list_buf[1] = NULL;
	addr_list = addr_list_buf;
    }

    for (ap = addr_list; *ap != NULL; ap++) {
	new_res = (struct addrinfo *)malloc(sizeof(struct addrinfo));
	if (new_res == NULL) {
	    if (head_res != NULL)
		freeaddrinfo(head_res);
	    result = EAI_MEMORY;
	    goto end;
	}

	new_res->ai_family = PF_INET;
	new_res->ai_socktype = hints->ai_socktype;
	new_res->ai_protocol = hints->ai_protocol;
	new_res->ai_addr = NULL;
	new_res->ai_addrlen = sizeof(struct sockaddr_in);
	new_res->ai_canonname = NULL;
	new_res->ai_next = NULL;

	new_res->ai_addr = (struct sockaddr *)
	    malloc(sizeof(struct sockaddr_in));
	if (new_res->ai_addr == NULL) {
	    free(new_res);
	    if (head_res != NULL)
		freeaddrinfo(head_res);
	    result = EAI_MEMORY;
	    goto end;
	}

	sa_in = (struct sockaddr_in *)new_res->ai_addr;
	memset(sa_in, 0, sizeof(struct sockaddr_in));
	sa_in->sin_family = PF_INET;
	sa_in->sin_port = port;
	memcpy(&sa_in->sin_addr, *ap, sizeof(struct in_addr));

	if (head_res == NULL)
	    head_res = new_res;
	else
	    tail_res->ai_next = new_res;
	tail_res = new_res;
    }

    if (canonname != NULL && head_res != NULL) {
	head_res->ai_canonname = (char *)malloc(strlen(canonname) + 1);
	if (head_res->ai_canonname != NULL)
	    strcpy(head_res->ai_canonname, canonname);
    }

    *res = head_res;

  end:
    h_errno = saved_h_errno;
#ifdef ENABLE_PTHREAD
    pthread_mutex_unlock(&gai_mutex);
#endif
    return result;
}

/*
 * getnameinfo().
 */
int
getnameinfo(sa, salen, node, nodelen, serv, servlen, flags)
    const struct sockaddr *sa;
    socklen_t salen;
    char *node;
    socklen_t nodelen;
    char *serv;
    socklen_t servlen;
    int flags;
{
    const struct sockaddr_in *sa_in = (const struct sockaddr_in *)sa;
    struct hostent *hostent;
    struct servent *servent;
    char *ntoa_address;
    int saved_h_errno;
    int result = 0;

#ifdef ENABLE_PTHREAD
    pthread_mutex_lock(&gai_mutex);
#endif

    saved_h_errno = h_errno;

    if (sa_in->sin_family != PF_INET) {
	result = EAI_FAMILY;
	goto end;
    } else if (node == NULL && serv == NULL) {
	result = EAI_NONAME;
	goto end;
    }

    if (serv != NULL && servlen > 0) {
	if (flags & NI_NUMERICSERV)
	    servent = NULL;
	else if (flags & NI_DGRAM)
	    servent = getservbyport(sa_in->sin_port, "udp");
	else
	    servent = getservbyport(sa_in->sin_port, "tcp");

	if (servent != NULL) {
	    if (servlen <= strlen(servent->s_name)) {
		result = EAI_OVERFLOW;
		goto end;
	    }
	    strcpy(serv, servent->s_name);
	} else {
	    if (servlen <= itoa_length(ntohs(sa_in->sin_port))) {
		result = EAI_OVERFLOW;
		goto end;
	    }
	    sprintf(serv, "%d", ntohs(sa_in->sin_port));
	}
    }

    if (node != NULL && nodelen > 0) {
	if (flags & NI_NUMERICHOST)
	    hostent = NULL;
	else {
	    hostent = gethostbyaddr((char *)&sa_in->sin_addr, 
		sizeof(struct in_addr), AF_INET);
	}
	if (hostent != NULL) {
	    if (nodelen <= strlen(hostent->h_name)) {
		result = EAI_OVERFLOW;
		goto end;
	    }
	    strcpy(node, hostent->h_name);
	} else {
	    if (flags & NI_NAMEREQD) {
		result = EAI_NONAME;
		goto end;
	    }
	    ntoa_address = inet_ntoa(sa_in->sin_addr);
	    if (nodelen <= strlen(ntoa_address)) {
		result = EAI_OVERFLOW;
		goto end;
	    }
	    strcpy(node, ntoa_address);
	}
		
    }

  end:
    h_errno = saved_h_errno;
#ifdef ENABLE_PTHREAD
    pthread_mutex_unlock(&gai_mutex);
#endif
    return result;
}

