/*
 * stolen from net-tools-1.59 and stripped down for busybox by
 *                      Erik Andersen <andersen@codepoet.org>
 *
 * Heavily modified by Manuel Novoa III       Mar 12, 2001
 *
 * Version:     $Id: inet_common.c,v 1.8 2004/03/10 07:42:38 mjn3 Exp $
 *
 */

#include "inet_common.h"
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "libbb.h"

#ifdef DEBUG
# include <resolv.h>
#endif


const char bb_INET_default[] = "default";

int INET_resolve(const char *name, struct sockaddr_in *s_in, int hostfirst)
{
	struct hostent *hp;
	struct netent *np;

	/* Grmpf. -FvK */
	s_in->sin_family = AF_INET;
	s_in->sin_port = 0;

	/* Default is special, meaning 0.0.0.0. */
	if (!strcmp(name, bb_INET_default)) {
		s_in->sin_addr.s_addr = INADDR_ANY;
		return (1);
	}
	/* Look to see if it's a dotted quad. */
	if (inet_aton(name, &s_in->sin_addr)) {
		return 0;
	}
	/* If we expect this to be a hostname, try hostname database first */
#ifdef DEBUG
	if (hostfirst) {
		bb_error_msg("gethostbyname (%s)", name);
	}
#endif
	if (hostfirst && (hp = gethostbyname(name)) != (struct hostent *) NULL) {
		memcpy((char *) &s_in->sin_addr, (char *) hp->h_addr_list[0],
			   sizeof(struct in_addr));
		return 0;
	}
	/* Try the NETWORKS database to see if this is a known network. */
#ifdef DEBUG
	bb_error_msg("getnetbyname (%s)", name);
#endif
	if ((np = getnetbyname(name)) != (struct netent *) NULL) {
		s_in->sin_addr.s_addr = htonl(np->n_net);
		return 1;
	}
	if (hostfirst) {
		/* Don't try again */
		errno = h_errno;
		return -1;
	}
#ifdef DEBUG
	res_init();
	_res.options |= RES_DEBUG;
#endif

#ifdef DEBUG
	bb_error_msg("gethostbyname (%s)", name);
#endif
	if ((hp = gethostbyname(name)) == (struct hostent *) NULL) {
		errno = h_errno;
		return -1;
	}
	memcpy((char *) &s_in->sin_addr, (char *) hp->h_addr_list[0],
		   sizeof(struct in_addr));

	return 0;
}

/* cache */
struct addr {
	struct sockaddr_in addr;
	char *name;
	int host;
	struct addr *next;
};

static struct addr *INET_nn = NULL;	/* addr-to-name cache           */

/* numeric: & 0x8000: default instead of *,
 *          & 0x4000: host instead of net,
 *          & 0x0fff: don't resolve
 */
int INET_rresolve(char *name, size_t len, struct sockaddr_in *s_in,
				  int numeric, unsigned int netmask)
{
	struct hostent *ent;
	struct netent *np;
	struct addr *pn;
	unsigned long ad, host_ad;
	int host = 0;

	/* Grmpf. -FvK */
	if (s_in->sin_family != AF_INET) {
#ifdef DEBUG
		bb_error_msg("rresolve: unsupport address family %d !",
				  s_in->sin_family);
#endif
		errno = EAFNOSUPPORT;
		return (-1);
	}
	ad = (unsigned long) s_in->sin_addr.s_addr;
#ifdef DEBUG
	bb_error_msg("rresolve: %08lx, mask %08x, num %08x", ad, netmask, numeric);
#endif
	if (ad == INADDR_ANY) {
		if ((numeric & 0x0FFF) == 0) {
			if (numeric & 0x8000)
				safe_strncpy(name, bb_INET_default, len);
			else
				safe_strncpy(name, "*", len);
			return (0);
		}
	}
	if (numeric & 0x0FFF) {
		safe_strncpy(name, inet_ntoa(s_in->sin_addr), len);
		return (0);
	}

	if ((ad & (~netmask)) != 0 || (numeric & 0x4000))
		host = 1;
#if 0
	INET_nn = NULL;
#endif
	pn = INET_nn;
	while (pn != NULL) {
		if (pn->addr.sin_addr.s_addr == ad && pn->host == host) {
			safe_strncpy(name, pn->name, len);
#ifdef DEBUG
			bb_error_msg("rresolve: found %s %08lx in cache",
					  (host ? "host" : "net"), ad);
#endif
			return (0);
		}
		pn = pn->next;
	}

	host_ad = ntohl(ad);
	np = NULL;
	ent = NULL;
	if (host) {
#ifdef DEBUG
		bb_error_msg("gethostbyaddr (%08lx)", ad);
#endif
		ent = gethostbyaddr((char *) &ad, 4, AF_INET);
		if (ent != NULL) {
			safe_strncpy(name, ent->h_name, len);
		}
	} else {
#ifdef DEBUG
		bb_error_msg("getnetbyaddr (%08lx)", host_ad);
#endif
		np = getnetbyaddr(host_ad, AF_INET);
		if (np != NULL) {
			safe_strncpy(name, np->n_name, len);
		}
	}
	if ((ent == NULL) && (np == NULL)) {
		safe_strncpy(name, inet_ntoa(s_in->sin_addr), len);
	}
	pn = (struct addr *) xmalloc(sizeof(struct addr));
	pn->addr = *s_in;
	pn->next = INET_nn;
	pn->host = host;
	pn->name = bb_xstrdup(name);
	INET_nn = pn;

	return (0);
}

#ifdef CONFIG_FEATURE_IPV6

int INET6_resolve(const char *name, struct sockaddr_in6 *sin6)
{
	struct addrinfo req, *ai;
	int s;

	memset(&req, '\0', sizeof req);
	req.ai_family = AF_INET6;
	if ((s = getaddrinfo(name, NULL, &req, &ai))) {
		bb_error_msg("getaddrinfo: %s: %d", name, s);
		return -1;
	}
	memcpy(sin6, ai->ai_addr, sizeof(struct sockaddr_in6));

	freeaddrinfo(ai);

	return (0);
}

#ifndef IN6_IS_ADDR_UNSPECIFIED
# define IN6_IS_ADDR_UNSPECIFIED(a) \
	(((__u32 *) (a))[0] == 0 && ((__u32 *) (a))[1] == 0 && \
	 ((__u32 *) (a))[2] == 0 && ((__u32 *) (a))[3] == 0)
#endif


int INET6_rresolve(char *name, size_t len, struct sockaddr_in6 *sin6,
				   int numeric)
{
	int s;

	/* Grmpf. -FvK */
	if (sin6->sin6_family != AF_INET6) {
#ifdef DEBUG
		bb_error_msg(_("rresolve: unsupport address family %d !\n"),
				  sin6->sin6_family);
#endif
		errno = EAFNOSUPPORT;
		return (-1);
	}
	if (numeric & 0x7FFF) {
		inet_ntop(AF_INET6, &sin6->sin6_addr, name, len);
		return (0);
	}
	if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
		if (numeric & 0x8000) {
			strcpy(name, "default");
		} else {
			strcpy(name, "*");
		}
		return (0);
	}

	s = getnameinfo((struct sockaddr *) sin6, sizeof(struct sockaddr_in6), name, len, NULL, 0, 0);
	if (s) {
		bb_error_msg("getnameinfo failed");
		return -1;
	}
	return (0);
}

#endif							/* CONFIG_FEATURE_IPV6 */
