/* vi: set sw=4 ts=4: */

//config:config NSLOOKUP
//config:	bool "nslookup (9.7 kb)"
//config:	default y
//config:	help
//config:	nslookup is a tool to query Internet name servers.
//config:
//config:config FEATURE_NSLOOKUP_BIG
//config:	bool "Use internal resolver code instead of libc"
//config:	depends on NSLOOKUP
//config:	default y
//config:
//config:config FEATURE_NSLOOKUP_LONG_OPTIONS
//config:	bool "Enable long options"
//config:	default y
//config:	depends on FEATURE_NSLOOKUP_BIG && LONG_OPTS

//applet:IF_NSLOOKUP(APPLET(nslookup, BB_DIR_USR_BIN, BB_SUID_DROP))

//kbuild:lib-$(CONFIG_NSLOOKUP) += nslookup.o

//usage:#define nslookup_trivial_usage
//usage:       IF_FEATURE_NSLOOKUP_BIG("[-type=QUERY_TYPE] [-debug] ") "HOST [DNS_SERVER]"
//usage:#define nslookup_full_usage "\n\n"
//usage:       "Query DNS about HOST"
//usage:       IF_FEATURE_NSLOOKUP_BIG("\n")
//usage:       IF_FEATURE_NSLOOKUP_BIG("\nQUERY_TYPE: soa,ns,a,"IF_FEATURE_IPV6("aaaa,")"cname,mx,txt,ptr,any")
//usage:#define nslookup_example_usage
//usage:       "$ nslookup localhost\n"
//usage:       "Server:     default\n"
//usage:       "Address:    default\n"
//usage:       "\n"
//usage:       "Name:       debian\n"
//usage:       "Address:    127.0.0.1\n"

#include <resolv.h>
#include <net/if.h>	/* for IFNAMSIZ */
//#include <arpa/inet.h>
//#include <netdb.h>
#include "libbb.h"
#include "common_bufsiz.h"


#if !ENABLE_FEATURE_NSLOOKUP_BIG

/*
 * Mini nslookup implementation for busybox
 *
 * Copyright (C) 1999,2000 by Lineo, inc. and John Beppu
 * Copyright (C) 1999,2000,2001 by John Beppu <beppu@codepoet.org>
 *
 * Correct default name server display and explicit name server option
 * added by Ben Zeckel <bzeckel@hmc.edu> June 2001
 *
 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
 */

/*
 * I'm only implementing non-interactive mode;
 * I totally forgot nslookup even had an interactive mode.
 *
 * This applet is the only user of res_init(). Without it,
 * you may avoid pulling in _res global from libc.
 */

/* Examples of 'standard' nslookup output
 * $ nslookup yahoo.com
 * Server:         128.193.0.10
 * Address:        128.193.0.10#53
 *
 * Non-authoritative answer:
 * Name:   yahoo.com
 * Address: 216.109.112.135
 * Name:   yahoo.com
 * Address: 66.94.234.13
 *
 * $ nslookup 204.152.191.37
 * Server:         128.193.4.20
 * Address:        128.193.4.20#53
 *
 * Non-authoritative answer:
 * 37.191.152.204.in-addr.arpa     canonical name = 37.32-27.191.152.204.in-addr.arpa.
 * 37.32-27.191.152.204.in-addr.arpa       name = zeus-pub2.kernel.org.
 *
 * Authoritative answers can be found from:
 * 32-27.191.152.204.in-addr.arpa  nameserver = ns1.kernel.org.
 * 32-27.191.152.204.in-addr.arpa  nameserver = ns2.kernel.org.
 * 32-27.191.152.204.in-addr.arpa  nameserver = ns3.kernel.org.
 * ns1.kernel.org  internet address = 140.211.167.34
 * ns2.kernel.org  internet address = 204.152.191.4
 * ns3.kernel.org  internet address = 204.152.191.36
 */

static int print_host(const char *hostname, const char *header)
{
	/* We can't use xhost2sockaddr() - we want to get ALL addresses,
	 * not just one */
	struct addrinfo *result = NULL;
	int rc;
	struct addrinfo hint;

	memset(&hint, 0 , sizeof(hint));
	/* hint.ai_family = AF_UNSPEC; - zero anyway */
	/* Needed. Or else we will get each address thrice (or more)
	 * for each possible socket type (tcp,udp,raw...): */
	hint.ai_socktype = SOCK_STREAM;
	// hint.ai_flags = AI_CANONNAME;
	rc = getaddrinfo(hostname, NULL /*service*/, &hint, &result);

	if (rc == 0) {
		struct addrinfo *cur = result;
		unsigned cnt = 0;

		printf("%-10s %s\n", header, hostname);
		// puts(cur->ai_canonname); ?
		while (cur) {
			char *dotted, *revhost;
			dotted = xmalloc_sockaddr2dotted_noport(cur->ai_addr);
			revhost = xmalloc_sockaddr2hostonly_noport(cur->ai_addr);

			printf("Address %u: %s%c", ++cnt, dotted, revhost ? ' ' : '\n');
			if (revhost) {
				puts(revhost);
				if (ENABLE_FEATURE_CLEAN_UP)
					free(revhost);
			}
			if (ENABLE_FEATURE_CLEAN_UP)
				free(dotted);
			cur = cur->ai_next;
		}
	} else {
#if ENABLE_VERBOSE_RESOLUTION_ERRORS
		bb_error_msg("can't resolve '%s': %s", hostname, gai_strerror(rc));
#else
		bb_error_msg("can't resolve '%s'", hostname);
#endif
	}
	if (ENABLE_FEATURE_CLEAN_UP && result)
		freeaddrinfo(result);
	return (rc != 0);
}

/* lookup the default nameserver and display it */
static void server_print(void)
{
	char *server;
	struct sockaddr *sa;

#if ENABLE_FEATURE_IPV6
	sa = (struct sockaddr*)_res._u._ext.nsaddrs[0];
	if (!sa)
#endif
		sa = (struct sockaddr*)&_res.nsaddr_list[0];
	server = xmalloc_sockaddr2dotted_noport(sa);

	print_host(server, "Server:");
	if (ENABLE_FEATURE_CLEAN_UP)
		free(server);
	bb_putchar('\n');
}

/* alter the global _res nameserver structure to use
   an explicit dns server instead of what is in /etc/resolv.conf */
static void set_default_dns(const char *server)
{
	len_and_sockaddr *lsa;

	if (!server)
		return;

	/* NB: this works even with, say, "[::1]:5353"! :) */
	lsa = xhost2sockaddr(server, 53);

	if (lsa->u.sa.sa_family == AF_INET) {
		_res.nscount = 1;
		/* struct copy */
		_res.nsaddr_list[0] = lsa->u.sin;
	}
#if ENABLE_FEATURE_IPV6
	/* Hoped libc can cope with IPv4 address there too.
	 * No such luck, glibc 2.4 segfaults even with IPv6,
	 * maybe I misunderstand how to make glibc use IPv6 addr?
	 * (uclibc 0.9.31+ should work) */
	if (lsa->u.sa.sa_family == AF_INET6) {
		// glibc neither SEGVs nor sends any dgrams with this
		// (strace shows no socket ops):
		//_res.nscount = 0;
		_res._u._ext.nscount = 1;
		/* store a pointer to part of malloc'ed lsa */
		_res._u._ext.nsaddrs[0] = &lsa->u.sin6;
		/* must not free(lsa)! */
	}
#endif
}

int nslookup_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int nslookup_main(int argc, char **argv)
{
	/* We allow 1 or 2 arguments.
	 * The first is the name to be looked up and the second is an
	 * optional DNS server with which to do the lookup.
	 * More than 3 arguments is an error to follow the pattern of the
	 * standard nslookup */
	if (!argv[1] || argv[1][0] == '-' || argc > 3)
		bb_show_usage();

	/* initialize DNS structure _res used in printing the default
	 * name server and in the explicit name server option feature. */
	res_init();
	/* rfc2133 says this enables IPv6 lookups */
	/* (but it also says "may be enabled in /etc/resolv.conf") */
	/*_res.options |= RES_USE_INET6;*/

	set_default_dns(argv[2]);

	server_print();

	/* getaddrinfo and friends are free to request a resolver
	 * reinitialization. Just in case, set_default_dns() again
	 * after getaddrinfo (in server_print). This reportedly helps
	 * with bug 675 "nslookup does not properly use second argument"
	 * at least on Debian Wheezy and Openwrt AA (eglibc based).
	 */
	set_default_dns(argv[2]);

	return print_host(argv[1], "Name:");
}


#else /****** A version from LEDE / OpenWRT ******/

/*
 * musl compatible nslookup
 *
 * Copyright (C) 2017 Jo-Philipp Wich <jo@mein.io>
 *
 * Permission to use, copy, modify, and/or 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.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#if 0
# define dbg(...) fprintf(stderr, __VA_ARGS__)
#else
# define dbg(...) ((void)0)
#endif

struct ns {
	const char *name;
	len_and_sockaddr *lsa;
	//UNUSED: int failures;
	int replies;
};

struct query {
	const char *name;
	unsigned qlen;
//	unsigned latency;
//	uint8_t rcode;
	unsigned char query[512];
//	unsigned char reply[512];
};

static const struct {
	unsigned char type;
	char name[7];
} qtypes[] = {
	{ ns_t_soa,   "SOA"   },
	{ ns_t_ns,    "NS"    },
	{ ns_t_a,     "A"     },
#if ENABLE_FEATURE_IPV6
	{ ns_t_aaaa,  "AAAA"  },
#endif
	{ ns_t_cname, "CNAME" },
	{ ns_t_mx,    "MX"    },
	{ ns_t_txt,   "TXT"   },
	{ ns_t_ptr,   "PTR"   },
	{ ns_t_any,   "ANY"   },
};

static const char *const rcodes[] = {
	"NOERROR",    // 0
	"FORMERR",    // 1
	"SERVFAIL",   // 2
	"NXDOMAIN",   // 3
	"NOTIMP",     // 4
	"REFUSED",    // 5
	"YXDOMAIN",   // 6
	"YXRRSET",    // 7
	"NXRRSET",    // 8
	"NOTAUTH",    // 9
	"NOTZONE",    // 10
	"11",         // 11 not assigned
	"12",         // 12 not assigned
	"13",         // 13 not assigned
	"14",         // 14 not assigned
	"15",         // 15 not assigned
};

#if ENABLE_FEATURE_IPV6
static const char v4_mapped[12] = { 0,0,0,0, 0,0,0,0, 0,0,0xff,0xff };
#endif

struct globals {
	unsigned default_port;
	unsigned default_retry;
	unsigned default_timeout;
	unsigned query_count;
	unsigned serv_count;
	struct ns *server;
	struct query *query;
	char *search;
	smalluint have_search_directive;
	smalluint exitcode;
} FIX_ALIASING;
#define G (*(struct globals*)bb_common_bufsiz1)
#define INIT_G() do { \
	setup_common_bufsiz(); \
	G.default_port = 53; \
	G.default_retry = 2; \
	G.default_timeout = 5; \
} while (0)

enum {
	OPT_debug = (1 << 0),
};

static int parse_reply(const unsigned char *msg, size_t len)
{
	HEADER *header;

	ns_msg handle;
	ns_rr rr;
	int i, n, rdlen;
	const char *format = NULL;
	char astr[INET6_ADDRSTRLEN], dname[MAXDNAME];
	const unsigned char *cp;

	header = (HEADER *)msg;
	if (!header->aa)
		printf("Non-authoritative answer:\n");

	if (ns_initparse(msg, len, &handle) != 0) {
		//printf("Unable to parse reply: %s\n", strerror(errno));
		return -1;
	}

	for (i = 0; i < ns_msg_count(handle, ns_s_an); i++) {
		if (ns_parserr(&handle, ns_s_an, i, &rr) != 0) {
			//printf("Unable to parse resource record: %s\n", strerror(errno));
			return -1;
		}

		rdlen = ns_rr_rdlen(rr);

		switch (ns_rr_type(rr))
		{
		case ns_t_a:
			if (rdlen != 4) {
				dbg("unexpected A record length %d\n", rdlen);
				return -1;
			}
			inet_ntop(AF_INET, ns_rr_rdata(rr), astr, sizeof(astr));
			printf("Name:\t%s\nAddress: %s\n", ns_rr_name(rr), astr);
			break;

#if ENABLE_FEATURE_IPV6
		case ns_t_aaaa:
			if (rdlen != 16) {
				dbg("unexpected AAAA record length %d\n", rdlen);
				return -1;
			}
			inet_ntop(AF_INET6, ns_rr_rdata(rr), astr, sizeof(astr));
			/* bind-utils-9.11.3 uses the same format for A and AAAA answers */
			printf("Name:\t%s\nAddress: %s\n", ns_rr_name(rr), astr);
			break;
#endif

		case ns_t_ns:
			if (!format)
				format = "%s\tnameserver = %s\n";
			/* fall through */

		case ns_t_cname:
			if (!format)
				format = "%s\tcanonical name = %s\n";
			/* fall through */

		case ns_t_ptr:
			if (!format)
				format = "%s\tname = %s\n";
			if (ns_name_uncompress(ns_msg_base(handle), ns_msg_end(handle),
					ns_rr_rdata(rr), dname, sizeof(dname)) < 0
			) {
				//printf("Unable to uncompress domain: %s\n", strerror(errno));
				return -1;
			}
			printf(format, ns_rr_name(rr), dname);
			break;

		case ns_t_mx:
			if (rdlen < 2) {
				printf("MX record too short\n");
				return -1;
			}
			n = ns_get16(ns_rr_rdata(rr));
			if (ns_name_uncompress(ns_msg_base(handle), ns_msg_end(handle),
					ns_rr_rdata(rr) + 2, dname, sizeof(dname)) < 0
			) {
				//printf("Cannot uncompress MX domain: %s\n", strerror(errno));
				return -1;
			}
			printf("%s\tmail exchanger = %d %s\n", ns_rr_name(rr), n, dname);
			break;

		case ns_t_txt:
			if (rdlen < 1) {
				//printf("TXT record too short\n");
				return -1;
			}
			n = *(unsigned char *)ns_rr_rdata(rr);
			if (n > 0) {
				memset(dname, 0, sizeof(dname));
				memcpy(dname, ns_rr_rdata(rr) + 1, n);
				printf("%s\ttext = \"%s\"\n", ns_rr_name(rr), dname);
			}
			break;

		case ns_t_soa:
			if (rdlen < 20) {
				dbg("SOA record too short:%d\n", rdlen);
				return -1;
			}

			printf("%s\n", ns_rr_name(rr));

			cp = ns_rr_rdata(rr);
			n = ns_name_uncompress(ns_msg_base(handle), ns_msg_end(handle),
			                       cp, dname, sizeof(dname));
			if (n < 0) {
				//printf("Unable to uncompress domain: %s\n", strerror(errno));
				return -1;
			}

			printf("\torigin = %s\n", dname);
			cp += n;

			n = ns_name_uncompress(ns_msg_base(handle), ns_msg_end(handle),
			                       cp, dname, sizeof(dname));
			if (n < 0) {
				//printf("Unable to uncompress domain: %s\n", strerror(errno));
				return -1;
			}

			printf("\tmail addr = %s\n", dname);
			cp += n;

			printf("\tserial = %lu\n", ns_get32(cp));
			cp += 4;

			printf("\trefresh = %lu\n", ns_get32(cp));
			cp += 4;

			printf("\tretry = %lu\n", ns_get32(cp));
			cp += 4;

			printf("\texpire = %lu\n", ns_get32(cp));
			cp += 4;

			printf("\tminimum = %lu\n", ns_get32(cp));
			break;

		default:
			break;
		}
	}

	return i;
}

/*
 * Function logic borrowed & modified from musl libc, res_msend.c
 * G.query_count is always > 0.
 */
static int send_queries(struct ns *ns)
{
	unsigned char reply[512];
	uint8_t rcode;
	len_and_sockaddr *local_lsa;
	struct pollfd pfd;
	int servfail_retry = 0;
	int n_replies = 0;
//	int save_idx = 0;
	unsigned retry_interval;
	unsigned timeout = G.default_timeout * 1000;
	unsigned tstart, tsent, tcur;

	pfd.events = POLLIN;
	pfd.fd = xsocket_type(&local_lsa, ns->lsa->u.sa.sa_family, SOCK_DGRAM);
	/*
	 * local_lsa has "null" address and port 0 now.
	 * bind() ensures we have a *particular port* selected by kernel
	 * and remembered in fd, thus later recv(fd)
	 * receives only packets sent to this port.
	 */
	xbind(pfd.fd, &local_lsa->u.sa, local_lsa->len);
	free(local_lsa);
	/* Make read/writes know the destination */
	xconnect(pfd.fd, &ns->lsa->u.sa, ns->lsa->len);
	ndelay_on(pfd.fd);

	retry_interval = timeout / G.default_retry;
	tstart = tcur = monotonic_ms();
	goto send;

	while (tcur - tstart < timeout) {
		int qn;
		int recvlen;

		if (tcur - tsent >= retry_interval) {
 send:
			for (qn = 0; qn < G.query_count; qn++) {
				if (G.query[qn].qlen == 0)
					continue; /* this one was replied already */

				if (write(pfd.fd, G.query[qn].query, G.query[qn].qlen) < 0) {
					bb_perror_msg("write to '%s'", ns->name);
					n_replies = -1; /* "no go, try next server" */
					goto ret;
				}
				dbg("query %u sent\n", qn);
			}
			tsent = tcur;
			servfail_retry = 2 * G.query_count;
		}

		/* Wait for a response, or until time to retry */
		if (poll(&pfd, 1, retry_interval - (tcur - tsent)) <= 0)
			goto next;

		recvlen = read(pfd.fd, reply, sizeof(reply));
		if (recvlen < 0) {
			bb_perror_msg("read");
 next:
			tcur = monotonic_ms();
			continue;
		}

		if (ns->replies++ == 0) {
			printf("Server:\t\t%s\n", ns->name);
			printf("Address:\t%s\n\n",
				auto_string(xmalloc_sockaddr2dotted(&ns->lsa->u.sa))
			);
			/* In "Address", bind-utils-9.11.3 show port after a hash: "1.2.3.4#53" */
			/* Should we do the same? */
		}

		/* Non-identifiable packet */
		if (recvlen < 4) {
			dbg("read is too short:%d\n", recvlen);
			goto next;
		}

		/* Find which query this answer goes with, if any */
//		qn = save_idx;
		qn = 0;
		for (;;) {
			if (memcmp(reply, G.query[qn].query, 2) == 0) {
				dbg("response matches query %u\n", qn);
				break;
			}
			if (++qn >= G.query_count) {
				dbg("response does not match any query\n");
				goto next;
			}
		}

		if (G.query[qn].qlen == 0) {
			dbg("dropped duplicate response to query %u\n", qn);
			goto next;
		}

		rcode = reply[3] & 0x0f;
		dbg("query %u rcode:%s\n", qn, rcodes[rcode]);

		/* Retry immediately on SERVFAIL */
		if (rcode == 2) {
			//UNUSED: ns->failures++;
			if (servfail_retry) {
				servfail_retry--;
				write(pfd.fd, G.query[qn].query, G.query[qn].qlen);
				dbg("query %u resent\n", qn);
				goto next;
			}
		}

		/* Process reply */
		G.query[qn].qlen = 0; /* flag: "reply received" */
		tcur = monotonic_ms();
#if 1
		if (option_mask32 & OPT_debug) {
			printf("Query #%d completed in %ums:\n", qn, tcur - tstart);
		}
		if (rcode != 0) {
			printf("** server can't find %s: %s\n",
					G.query[qn].name, rcodes[rcode]);
			G.exitcode = EXIT_FAILURE;
		} else {
			if (parse_reply(reply, recvlen) < 0) {
				printf("*** Can't find %s: Parse error\n", G.query[qn].name);
				G.exitcode = EXIT_FAILURE;
			}
		}
		bb_putchar('\n');
		n_replies++;
		if (n_replies >= G.query_count)
			goto ret;
#else
//used to store replies and process them later
		G.query[qn].latency = tcur - tstart;
		n_replies++;
		if (qn != save_idx) {
			/* "wrong" receive buffer, move to correct one */
			memcpy(G.query[qn].reply, G.query[save_idx].reply, recvlen);
			continue;
		}
		/* G.query[0..save_idx] have replies, move to next one, if exists */
		for (;;) {
			save_idx++;
			if (save_idx >= G.query_count)
				goto ret; /* all are full: we have all results */
			if (!G.query[save_idx].rlen)
				break; /* this one is empty */
		}
#endif
	} /* while() */

 ret:
	close(pfd.fd);

	return n_replies;
}

static void add_ns(const char *addr)
{
	struct ns *ns;
	unsigned count;

	dbg("%s: addr:'%s'\n", __func__, addr);

	count = G.serv_count++;

	G.server = xrealloc_vector(G.server, /*8=2^3:*/ 3, count);
	ns = &G.server[count];
	ns->name = addr;
	ns->lsa = xhost2sockaddr(addr, G.default_port);
	/*ns->replies = 0; - already is */
	/*ns->failures = 0; - already is */
}

static void parse_resolvconf(void)
{
	FILE *resolv;

	resolv = fopen("/etc/resolv.conf", "r");
	if (resolv) {
		char line[512];	/* "search" is defined to be up to 256 chars */

		while (fgets(line, sizeof(line), resolv)) {
			char *p, *arg;

			p = strtok(line, " \t\n");
			if (!p)
				continue;
			dbg("resolv_key:'%s'\n", p);
			arg = strtok(NULL, "\n");
			dbg("resolv_arg:'%s'\n", arg);
			if (!arg)
				continue;

			if (strcmp(p, "domain") == 0) {
				/* domain DOM */
				if (!G.have_search_directive)
					goto set_search;
				continue;
			}
			if (strcmp(p, "search") == 0) {
				/* search DOM1 DOM2... */
				G.have_search_directive = 1;
 set_search:
				free(G.search);
				G.search = xstrdup(arg);
				dbg("search='%s'\n", G.search);
				continue;
			}

			if (strcmp(p, "nameserver") != 0)
				continue;

			/* nameserver DNS */
			add_ns(xstrdup(arg));
		}

		fclose(resolv);
	}

	if (!G.search) {
		/* default search domain is domain part of hostname */
		char *h = safe_gethostname();
		char *d = strchr(h, '.');
		if (d) {
			G.search = d + 1;
			dbg("search='%s' (from hostname)\n", G.search);
		}
		/* else free(h); */
	}

	/* Cater for case of "domain ." in resolv.conf */
	if (G.search && LONE_CHAR(G.search, '.'))
		G.search = NULL;
}

static void add_query(int type, const char *dname)
{
	struct query *new_q;
	unsigned count;
	ssize_t qlen;

	count = G.query_count++;

	G.query = xrealloc_vector(G.query, /*4=2^2:*/ 2, count);
	new_q = &G.query[count];

	dbg("new query#%u type %u for '%s'\n", count, type, dname);
	new_q->name = dname;

	qlen = res_mkquery(QUERY, dname, C_IN, type,
			/*data:*/ NULL, /*datalen:*/ 0,
			/*newrr:*/ NULL,
			new_q->query, sizeof(new_q->query)
	);
	new_q->qlen = qlen;
}

static void add_query_with_search(int type, const char *dname)
{
	char *s;

	if (type == T_PTR || !G.search || strchr(dname, '.')) {
		add_query(type, dname);
		return;
	}

	s = G.search;
	for (;;) {
		char *fullname, *e;

		e = skip_non_whitespace(s);
		fullname = xasprintf("%s.%.*s", dname, (int)(e - s), s);
		add_query(type, fullname);
		s = skip_whitespace(e);
		if (!*s)
			break;
	}
}

static char *make_ptr(const char *addrstr)
{
	unsigned char addr[16];

#if ENABLE_FEATURE_IPV6
	if (inet_pton(AF_INET6, addrstr, addr)) {
		if (memcmp(addr, v4_mapped, 12) != 0) {
			int i;
			char resbuf[80];
			char *ptr = resbuf;
			for (i = 0; i < 16; i++) {
				*ptr++ = 0x20 | bb_hexdigits_upcase[(unsigned char)addr[15 - i] & 0xf];
				*ptr++ = '.';
				*ptr++ = 0x20 | bb_hexdigits_upcase[(unsigned char)addr[15 - i] >> 4];
				*ptr++ = '.';
			}
			strcpy(ptr, "ip6.arpa");
			return xstrdup(resbuf);
		}
		return xasprintf("%u.%u.%u.%u.in-addr.arpa",
				addr[15], addr[14], addr[13], addr[12]);
	}
#endif

	if (inet_pton(AF_INET, addrstr, addr)) {
		return xasprintf("%u.%u.%u.%u.in-addr.arpa",
		        addr[3], addr[2], addr[1], addr[0]);
	}

	return NULL;
}

int nslookup_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int nslookup_main(int argc UNUSED_PARAM, char **argv)
{
	unsigned types;
	int rc;
	int err;

	INIT_G();

	/* manpage: "Options can also be specified on the command line
	 * if they precede the arguments and are prefixed with a hyphen."
	 */
	types = 0;
	argv++;
	for (;;) {
		const char *options =
// bind-utils-9.11.3 accept these:
// class=   cl=
// type=    ty= querytype= query= qu= q=
// domain=  do=
// port=    po=
// timeout= t=
// retry=   ret=
// ndots=
// recurse
// norecurse
// defname
// nodefname
// vc
// novc
// debug
// nodebug
// d2
// nod2
// search
// nosearch
// sil
// fail
// nofail
// ver (prints version and exits)
			"type\0"      /* 0 */
			"querytype\0" /* 1 */
			"port\0"      /* 2 */
			"retry\0"     /* 3 */
			"debug\0"     /* 4 */
			"t\0" /* disambiguate with "type": else -t=2 fails */
			"timeout\0"   /* 6 */
			"";
		int i;
		char *arg;
		char *val;

		if (!*argv)
			bb_show_usage();
		if (argv[0][0] != '-')
			break;

		/* Separate out "=val" part */
		arg = (*argv++) + 1;
		val = strchrnul(arg, '=');
		if (*val)
			*val++ = '\0';

		i = index_in_substrings(options, arg);
		//bb_error_msg("i:%d arg:'%s' val:'%s'", i, arg, val);
		if (i < 0)
			bb_show_usage();

		if (i <= 1) {
			for (i = 0;; i++) {
				if (i == ARRAY_SIZE(qtypes))
					bb_error_msg_and_die("invalid query type \"%s\"", val);
				if (strcasecmp(qtypes[i].name, val) == 0)
					break;
			}
			types |= (1 << i);
			continue;
		}
		if (i == 2) {
			G.default_port = xatou_range(val, 1, 0xffff);
		}
		if (i == 3) {
			G.default_retry = xatou_range(val, 1, INT_MAX);
		}
		if (i == 4) {
			option_mask32 |= OPT_debug;
		}
		if (i > 4) {
			G.default_timeout = xatou_range(val, 1, INT_MAX / 1000);
		}
	}

	/* Use given DNS server if present */
	if (argv[1]) {
		if (argv[2])
			bb_show_usage();
		add_ns(argv[1]);
	} else {
		parse_resolvconf();
		/* Fall back to localhost if we could not find NS in resolv.conf */
		if (G.serv_count == 0)
			add_ns("127.0.0.1");
	}

	if (types == 0) {
		/* No explicit type given, guess query type.
		 * If we can convert the domain argument into a ptr (means that
		 * inet_pton() could read it) we assume a PTR request, else
		 * we issue A+AAAA queries and switch to an output format
		 * mimicking the one of the traditional nslookup applet.
		 */
		char *ptr;

		ptr = make_ptr(argv[0]);
		if (ptr) {
			add_query(T_PTR, ptr);
		} else {
			add_query_with_search(T_A, argv[0]);
#if ENABLE_FEATURE_IPV6
			add_query_with_search(T_AAAA, argv[0]);
#endif
		}
	} else {
		int c;
		for (c = 0; c < ARRAY_SIZE(qtypes); c++) {
			if (types & (1 << c))
				add_query_with_search(qtypes[c].type, argv[0]);
		}
	}

	for (rc = 0; rc < G.serv_count;) {
		int c;

		c = send_queries(&G.server[rc]);
		if (c > 0) {
			/* more than zero replies received */
#if 0 /* which version does this? */
			if (option_mask32 & OPT_debug) {
				printf("Replies:\t%d\n", G.server[rc].replies);
				printf("Failures:\t%d\n\n", G.server[rc].failures);
			}
#endif
			break;
//FIXME: we "break" even though some queries may still be not answered, and other servers may know them?
		}
		/* c = 0: timed out waiting for replies */
		/* c < 0: error (message already printed) */
		rc++;
		if (rc >= G.serv_count) {
//
// NB: bind-utils-9.11.3 behavior (all to stdout, not stderr):
//
// $ nslookup gmail.com 8.8.8.8
// ;; connection timed out; no servers could be reached
//
// Using TCP mode:
// $ nslookup -vc gmail.com 8.8.8.8; echo EXITCODE:$?
//     <~10 sec>
// ;; Connection to 8.8.8.8#53(8.8.8.8) for gmail.com failed: timed out.
//     <~10 sec>
// ;; Connection to 8.8.8.8#53(8.8.8.8) for gmail.com failed: timed out.
//     <~10 sec>
// ;; connection timed out; no servers could be reached
// ;; Connection to 8.8.8.8#53(8.8.8.8) for gmail.com failed: timed out.
//     <empty line>
// EXITCODE:1
// $ _
			printf(";; connection timed out; no servers could be reached\n\n");
			return EXIT_FAILURE;
		}
	}

	err = 0;
	for (rc = 0; rc < G.query_count; rc++) {
		if (G.query[rc].qlen) {
			printf("*** Can't find %s: No answer\n", G.query[rc].name);
			err = 1;
		}
	}
	if (err) /* should this affect exicode too? */
		bb_putchar('\n');

	if (ENABLE_FEATURE_CLEAN_UP) {
		free(G.server);
		free(G.query);
	}

	return G.exitcode;
}

#endif
