1*cca81d59Schristos /* $NetBSD: h_hostent.c,v 1.2 2014/01/09 02:18:10 christos Exp $ */
20f567347Schristos
30f567347Schristos /*-
40f567347Schristos * Copyright (c) 2013 The NetBSD Foundation, Inc.
50f567347Schristos * All rights reserved.
60f567347Schristos *
70f567347Schristos * This code is derived from software contributed to The NetBSD Foundation
80f567347Schristos * by Christos Zoulas.
90f567347Schristos *
100f567347Schristos * Redistribution and use in source and binary forms, with or without
110f567347Schristos * modification, are permitted provided that the following conditions
120f567347Schristos * are met:
130f567347Schristos * 1. Redistributions of source code must retain the above copyright
140f567347Schristos * notice, this list of conditions and the following disclaimer.
150f567347Schristos * 2. Redistributions in binary form must reproduce the above copyright
160f567347Schristos * notice, this list of conditions and the following disclaimer in the
170f567347Schristos * documentation and/or other materials provided with the distribution.
180f567347Schristos *
190f567347Schristos * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
200f567347Schristos * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
210f567347Schristos * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
220f567347Schristos * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
230f567347Schristos * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
240f567347Schristos * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
250f567347Schristos * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
260f567347Schristos * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
270f567347Schristos * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
280f567347Schristos * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
290f567347Schristos * POSSIBILITY OF SUCH DAMAGE.
300f567347Schristos */
310f567347Schristos #include <sys/cdefs.h>
32*cca81d59Schristos __RCSID("$NetBSD: h_hostent.c,v 1.2 2014/01/09 02:18:10 christos Exp $");
330f567347Schristos
340f567347Schristos #include <stdio.h>
350f567347Schristos #include <string.h>
360f567347Schristos #include <nsswitch.h>
370f567347Schristos #include <netdb.h>
380f567347Schristos #include <stdint.h>
390f567347Schristos #include <stdlib.h>
400f567347Schristos #include <unistd.h>
410f567347Schristos #include <err.h>
420f567347Schristos
430f567347Schristos #include <netinet/in.h>
440f567347Schristos #include <sys/types.h>
450f567347Schristos #include <arpa/nameser.h>
460f567347Schristos #include <arpa/inet.h>
470f567347Schristos
480f567347Schristos #include "hostent.h"
490f567347Schristos
50*cca81d59Schristos extern const char *__res_conf_name;
51*cca81d59Schristos
520f567347Schristos static void
phostent(const struct hostent * h)530f567347Schristos phostent(const struct hostent *h)
540f567347Schristos {
550f567347Schristos size_t i;
560f567347Schristos char buf[1024];
570f567347Schristos const int af = h->h_length == NS_INADDRSZ ? AF_INET : AF_INET6;
580f567347Schristos
590f567347Schristos printf("name=%s, length=%d, addrtype=%d, aliases=[",
600f567347Schristos h->h_name, h->h_length, h->h_addrtype);
610f567347Schristos
620f567347Schristos for (i = 0; h->h_aliases[i]; i++)
630f567347Schristos printf("%s%s", i == 0 ? "" : " ", h->h_aliases[i]);
640f567347Schristos
650f567347Schristos printf("] addr_list=[");
660f567347Schristos
670f567347Schristos for (i = 0; h->h_addr_list[i]; i++)
680f567347Schristos printf("%s%s", i == 0 ? "" : " ", inet_ntop(af,
690f567347Schristos h->h_addr_list[i], buf, (socklen_t)sizeof(buf)));
700f567347Schristos
710f567347Schristos printf("]\n");
720f567347Schristos }
730f567347Schristos
740f567347Schristos static void
usage(void)750f567347Schristos usage(void)
760f567347Schristos {
770f567347Schristos (void)fprintf(stderr, "Usage: %s [-f <hostsfile>] "
780f567347Schristos "[-t <any|dns|nis|files>] "
790f567347Schristos "[-46a] <name|address>\n", getprogname());
800f567347Schristos exit(EXIT_FAILURE);
810f567347Schristos }
820f567347Schristos
830f567347Schristos static void
getby(int (* f)(void *,void *,va_list),struct getnamaddr * info,...)840f567347Schristos getby(int (*f)(void *, void *, va_list), struct getnamaddr *info, ...)
850f567347Schristos {
860f567347Schristos va_list ap;
870f567347Schristos int e;
880f567347Schristos
890f567347Schristos va_start(ap, info);
900f567347Schristos e = (*f)(info, NULL, ap);
910f567347Schristos va_end(ap);
920f567347Schristos switch (e) {
930f567347Schristos case NS_SUCCESS:
940f567347Schristos phostent(info->hp);
950f567347Schristos break;
960f567347Schristos default:
970f567347Schristos printf("error %d\n", e);
980f567347Schristos break;
990f567347Schristos }
1000f567347Schristos }
1010f567347Schristos
1020f567347Schristos static void
geta(struct hostent * hp)1030f567347Schristos geta(struct hostent *hp) {
1040f567347Schristos if (hp == NULL)
1050f567347Schristos printf("error %d\n", h_errno);
1060f567347Schristos else
1070f567347Schristos phostent(hp);
1080f567347Schristos }
1090f567347Schristos
1100f567347Schristos int
main(int argc,char * argv[])1110f567347Schristos main(int argc, char *argv[])
1120f567347Schristos {
1130f567347Schristos int (*f)(void *, void *, va_list) = NULL;
1140f567347Schristos const char *type = "any";
1150f567347Schristos int c, af, e, byaddr, len;
1160f567347Schristos struct hostent hent;
1170f567347Schristos struct getnamaddr info;
1180f567347Schristos char buf[4096];
1190f567347Schristos
1200f567347Schristos af = AF_INET;
1210f567347Schristos byaddr = 0;
1220f567347Schristos len = 0;
1230f567347Schristos info.hp = &hent;
1240f567347Schristos info.buf = buf;
1250f567347Schristos info.buflen = sizeof(buf);
1260f567347Schristos info.he = &e;
1270f567347Schristos
128*cca81d59Schristos while ((c = getopt(argc, argv, "46af:r:t:")) != -1) {
1290f567347Schristos switch (c) {
1300f567347Schristos case '4':
1310f567347Schristos af = AF_INET;
1320f567347Schristos break;
1330f567347Schristos case '6':
1340f567347Schristos af = AF_INET6;
1350f567347Schristos break;
1360f567347Schristos case 'a':
1370f567347Schristos byaddr++;
1380f567347Schristos break;
1390f567347Schristos case 'f':
1400f567347Schristos _hf_sethostsfile(optarg);
1410f567347Schristos break;
142*cca81d59Schristos case 'r':
143*cca81d59Schristos __res_conf_name = optarg;
144*cca81d59Schristos break;
145*cca81d59Schristos case 't':
146*cca81d59Schristos type = optarg;
147*cca81d59Schristos break;
1480f567347Schristos default:
1490f567347Schristos usage();
1500f567347Schristos }
1510f567347Schristos }
1520f567347Schristos
1530f567347Schristos argc -= optind;
1540f567347Schristos argv += optind;
1550f567347Schristos
1560f567347Schristos if (argc != 1)
1570f567347Schristos usage();
1580f567347Schristos
1590f567347Schristos switch (*type) {
1600f567347Schristos case 'a':
1610f567347Schristos break;
1620f567347Schristos case 'd':
1630f567347Schristos f = byaddr ? _dns_gethtbyaddr : _dns_gethtbyname;
1640f567347Schristos break;
1650f567347Schristos #ifdef YP
1660f567347Schristos case 'n':
1670f567347Schristos f = byaddr ? _yp_gethtbyaddr : _yp_gethtbyname;
1680f567347Schristos break;
1690f567347Schristos #endif
1700f567347Schristos case 'f':
1710f567347Schristos f = byaddr ? _hf_gethtbyaddr : _hf_gethtbyname;
1720f567347Schristos break;
1730f567347Schristos default:
1740f567347Schristos errx(EXIT_FAILURE, "Unknown db type `%s'", type);
1750f567347Schristos }
1760f567347Schristos
1770f567347Schristos if (byaddr) {
1780f567347Schristos struct in6_addr addr;
1790f567347Schristos af = strchr(*argv, ':') ? AF_INET6 : AF_INET;
1800f567347Schristos len = af == AF_INET ? NS_INADDRSZ : NS_IN6ADDRSZ;
1810f567347Schristos if (inet_pton(af, *argv, &addr) == -1)
1820f567347Schristos err(EXIT_FAILURE, "Can't parse `%s'", *argv);
1830f567347Schristos if (*type == 'a')
1840f567347Schristos geta(gethostbyaddr((const char *)&addr, len, af));
1850f567347Schristos else
1860f567347Schristos getby(f, &info, &addr, len, af);
1870f567347Schristos } else {
1880f567347Schristos if (*type == 'a')
1890f567347Schristos geta(gethostbyname2(*argv, af));
1900f567347Schristos else
1910f567347Schristos getby(f, &info, *argv, len, af);
1920f567347Schristos }
1930f567347Schristos
1940f567347Schristos return 0;
1950f567347Schristos }
196