From 0f567347d0cc4ad0fc1b7ffa5051cd15e48ad4d0 Mon Sep 17 00:00:00 2001 From: christos Date: Fri, 16 Aug 2013 15:29:45 +0000 Subject: [PATCH] test harness for gethostbyname()/gethostbyaddr() and their internal bits. XXX[1]: How can we avoid using hard-coded hosts for DNS XXX[2]: How do we test NIS? --- tests/lib/libc/net/Makefile | 11 +- tests/lib/libc/net/h_hostent.c | 190 ++++++++++++++++++++++++++++++++ tests/lib/libc/net/hosts | 11 ++ tests/lib/libc/net/t_hostent.sh | 188 +++++++++++++++++++++++++++++++ 4 files changed, 399 insertions(+), 1 deletion(-) create mode 100644 tests/lib/libc/net/h_hostent.c create mode 100644 tests/lib/libc/net/hosts create mode 100644 tests/lib/libc/net/t_hostent.sh diff --git a/tests/lib/libc/net/Makefile b/tests/lib/libc/net/Makefile index d7807a2f46c5..a75c23c215b1 100644 --- a/tests/lib/libc/net/Makefile +++ b/tests/lib/libc/net/Makefile @@ -1,10 +1,11 @@ -# $NetBSD: Makefile,v 1.7 2012/09/15 16:22:58 plunky Exp $ +# $NetBSD: Makefile,v 1.8 2013/08/16 15:29:45 christos Exp $ .include MKMAN= no TESTS_SUBDIRS+= getaddrinfo +FILES+=hosts TESTSDIR= ${TESTSBASE}/lib/libc/net @@ -19,12 +20,20 @@ aton_ether_subr.c: gen_ether_subr ${NETBSDSRCDIR}/sys/net/if_ethersubr.c TESTS_SH+= t_nsdispatch TESTS_SH+= t_protoent TESTS_SH+= t_servent +TESTS_SH+= t_hostent BINDIR= ${TESTSDIR} PROGS+= h_nsd_recurse PROGS+= h_protoent PROGS+= h_servent +PROGS+= h_hostent +CPPFLAGS.h_hostent.c += -I${NETBSDSRCDIR}/lib/libc/net + +# For easy debugging, without installing libc +#.PATH.c:${NETBSDSRCDIR}/lib/libc/net +#SRCS.h_hostent = h_hostent.c gethnamaddr.c +#DBG=-g3 LDADD.h_nsd_recurse+= -lpthread diff --git a/tests/lib/libc/net/h_hostent.c b/tests/lib/libc/net/h_hostent.c new file mode 100644 index 000000000000..bfcdd0db4a84 --- /dev/null +++ b/tests/lib/libc/net/h_hostent.c @@ -0,0 +1,190 @@ +/* $NetBSD: h_hostent.c,v 1.1 2013/08/16 15:29:45 christos Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ +#include +__RCSID("$NetBSD: h_hostent.c,v 1.1 2013/08/16 15:29:45 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "hostent.h" + +static void +phostent(const struct hostent *h) +{ + size_t i; + char buf[1024]; + const int af = h->h_length == NS_INADDRSZ ? AF_INET : AF_INET6; + + printf("name=%s, length=%d, addrtype=%d, aliases=[", + h->h_name, h->h_length, h->h_addrtype); + + for (i = 0; h->h_aliases[i]; i++) + printf("%s%s", i == 0 ? "" : " ", h->h_aliases[i]); + + printf("] addr_list=["); + + for (i = 0; h->h_addr_list[i]; i++) + printf("%s%s", i == 0 ? "" : " ", inet_ntop(af, + h->h_addr_list[i], buf, (socklen_t)sizeof(buf))); + + printf("]\n"); +} + +static void +usage(void) +{ + (void)fprintf(stderr, "Usage: %s [-f ] " + "[-t ] " + "[-46a] \n", getprogname()); + exit(EXIT_FAILURE); +} + +static void +getby(int (*f)(void *, void *, va_list), struct getnamaddr *info, ...) +{ + va_list ap; + int e; + + va_start(ap, info); + e = (*f)(info, NULL, ap); + va_end(ap); + switch (e) { + case NS_SUCCESS: + phostent(info->hp); + break; + default: + printf("error %d\n", e); + break; + } +} + +static void +geta(struct hostent *hp) { + if (hp == NULL) + printf("error %d\n", h_errno); + else + phostent(hp); +} + +int +main(int argc, char *argv[]) +{ + int (*f)(void *, void *, va_list) = NULL; + const char *type = "any"; + int c, af, e, byaddr, len; + struct hostent hent; + struct getnamaddr info; + char buf[4096]; + + af = AF_INET; + byaddr = 0; + len = 0; + info.hp = &hent; + info.buf = buf; + info.buflen = sizeof(buf); + info.he = &e; + + while ((c = getopt(argc, argv, "46af:t:")) != -1) { + switch (c) { + case '4': + af = AF_INET; + break; + case '6': + af = AF_INET6; + break; + case 'a': + byaddr++; + break; + case 't': + type = optarg; + break; + case 'f': + _hf_sethostsfile(optarg); + break; + default: + usage(); + } + } + + argc -= optind; + argv += optind; + + if (argc != 1) + usage(); + + switch (*type) { + case 'a': + break; + case 'd': + f = byaddr ? _dns_gethtbyaddr : _dns_gethtbyname; + break; +#ifdef YP + case 'n': + f = byaddr ? _yp_gethtbyaddr : _yp_gethtbyname; + break; +#endif + case 'f': + f = byaddr ? _hf_gethtbyaddr : _hf_gethtbyname; + break; + default: + errx(EXIT_FAILURE, "Unknown db type `%s'", type); + } + + if (byaddr) { + struct in6_addr addr; + af = strchr(*argv, ':') ? AF_INET6 : AF_INET; + len = af == AF_INET ? NS_INADDRSZ : NS_IN6ADDRSZ; + if (inet_pton(af, *argv, &addr) == -1) + err(EXIT_FAILURE, "Can't parse `%s'", *argv); + if (*type == 'a') + geta(gethostbyaddr((const char *)&addr, len, af)); + else + getby(f, &info, &addr, len, af); + } else { + if (*type == 'a') + geta(gethostbyname2(*argv, af)); + else + getby(f, &info, *argv, len, af); + } + + return 0; +} diff --git a/tests/lib/libc/net/hosts b/tests/lib/libc/net/hosts new file mode 100644 index 000000000000..87ccbe8884a0 --- /dev/null +++ b/tests/lib/libc/net/hosts @@ -0,0 +1,11 @@ +# $NetBSD: hosts,v 1.1 2013/08/16 15:29:45 christos Exp $ +# +# Host Database +# This file should contain the addresses and aliases +# for local hosts that share this file. +# It is used only for "ifconfig" and other operations +# before the nameserver is started. +# +# +::1 localhost localhost. localhost.localdomain. +127.0.0.1 localhost localhost. localhost.localdomain. diff --git a/tests/lib/libc/net/t_hostent.sh b/tests/lib/libc/net/t_hostent.sh new file mode 100644 index 000000000000..b0a7f3e831ea --- /dev/null +++ b/tests/lib/libc/net/t_hostent.sh @@ -0,0 +1,188 @@ +# $NetBSD: t_hostent.sh,v 1.1 2013/08/16 15:29:45 christos Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# All rights reserved. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +n6="sixthavenue.astron.com" +a6="2620:106:3000:100:2e0:81ff:fe2f:e5d6" +ans6="name=$n6, length=16, addrtype=24, aliases=[] addr_list=[$a6]\n" + +n4="sixthavenue.astron.com" +a4="208.77.212.99" +ans4="name=$n4, length=4, addrtype=2, aliases=[] addr_list=[$a4]\n" + +l6="localhost" +al6="::1" +loc6="name=$l6, length=16, addrtype=24, aliases=[localhost. localhost.localdomain.] addr_list=[$al6]\n" + +l4="localhost" +al4="127.0.0.1" +loc4="name=$l4, length=4, addrtype=2, aliases=[localhost. localhost.localdomain.] addr_list=[$al4]\n" + +atf_test_case gethostbyname4 +gethostbyname4_head() +{ + atf_set "descr" "Checks gethostbyname2(3) for AF_INET (auto, as determined by nsswitch.conf(5)" +} +gethostbyname4_body() +{ + atf_check -o inline:"$ans4" -x "$(atf_get_srcdir)/h_hostent -t auto -4 $n4" +} + +atf_test_case gethostbyname6 +gethostbyname6_head() +{ + atf_set "descr" "Checks gethostbyname2(3) for AF_INET6 (auto, as determined by nsswitch.conf(5)" +} +gethostbyname6_body() +{ + atf_check -o inline:"$ans6" -x "$(atf_get_srcdir)/h_hostent -t auto -6 $n6" +} + +atf_test_case gethostbyaddr4 +gethostbyaddr4_head() +{ + atf_set "descr" "Checks gethostbyaddr(3) for AF_INET (auto, as determined by nsswitch.conf(5)" +} +gethostbyaddr4_body() +{ + atf_check -o inline:"$ans4" -x "$(atf_get_srcdir)/h_hostent -t auto -a $a4" +} + +atf_test_case gethostbyaddr6 +gethostbyaddr6_head() +{ + atf_set "descr" "Checks gethostbyaddr(3) for AF_INET6 (auto, as determined by nsswitch.conf(5)" +} +gethostbyaddr6_body() +{ + atf_check -o inline:"$ans6" -x "$(atf_get_srcdir)/h_hostent -t auto -a $a6" +} + +atf_test_case hostsbynamelookup4 +hostsbynamelookup4_head() +{ + atf_set "descr" "Checks /etc/hosts name lookup for AF_INET" +} +hostsbynamelookup4_body() +{ + local dir=$(atf_get_srcdir) + atf_check -o inline:"$loc4" -x "$dir/h_hostent -f $dir/hosts -t file -4 $l4" +} + +atf_test_case hostsbynamelookup6 +hostsbynamelookup6_head() +{ + atf_set "descr" "Checks /etc/hosts name lookup for AF_INET6" +} +hostsbynamelookup6_body() +{ + local dir=$(atf_get_srcdir) + atf_check -o inline:"$loc6" -x "$dir/h_hostent -f $dir/hosts -t file -6 $l6" +} + +atf_test_case hostsbyaddrlookup4 +hostsbyaddrlookup4_head() +{ + atf_set "descr" "Checks /etc/hosts address lookup for AF_INET" +} +hostsbyaddrlookup4_body() +{ + local dir=$(atf_get_srcdir) + atf_check -o inline:"$loc4" -x "$dir/h_hostent -f $dir/hosts -t file -4 -a $al4" +} + +atf_test_case hostsbyaddrlookup6 +hostsbyaddrlookup6_head() +{ + atf_set "descr" "Checks /etc/hosts address lookup for AF_INET6" +} +hostsbyaddrlookup6_body() +{ + local dir=$(atf_get_srcdir) + atf_check -o inline:"$loc6" -x "$dir/h_hostent -f $dir/hosts -t file -6 -a $al6" +} + +atf_test_case dnsbynamelookup4 +dnsbynamelookup4_head() +{ + atf_set "descr" "Checks DNS name lookup for AF_INET" +} +dnsbynamelookup4_body() +{ + local dir=$(atf_get_srcdir) + atf_check -o inline:"$ans4" -x "$dir/h_hostent -t dns -4 $n4" +} + +atf_test_case dnsbynamelookup6 +dnsbynamelookup6_head() +{ + atf_set "descr" "Checks DNS name lookup for AF_INET6" +} +dnsbynamelookup6_body() +{ + local dir=$(atf_get_srcdir) + atf_check -o inline:"$ans6" -x "$dir/h_hostent -t dns -6 $n6" +} + +atf_test_case dnsbyaddrlookup4 +dnsbyaddrlookup4_head() +{ + atf_set "descr" "Checks DNS address lookup for AF_INET" +} +dnsbyaddrlookup4_body() +{ + local dir=$(atf_get_srcdir) + atf_check -o inline:"$ans4" -x "$dir/h_hostent -t dns -4 -a $a4" +} + +atf_test_case dnsbyaddrlookup6 +dnsbyaddrlookup6_head() +{ + atf_set "descr" "Checks dns address lookup for AF_INET6" +} +dnsbyaddrlookup6_body() +{ + local dir=$(atf_get_srcdir) + atf_check -o inline:"$ans6" -x "$dir/h_hostent -t dns -6 -a $a6" +} + +atf_init_test_cases() +{ + atf_add_test_case gethostbyname4 + atf_add_test_case gethostbyname6 + atf_add_test_case gethostbyaddr4 + atf_add_test_case gethostbyaddr6 + + atf_add_test_case hostsbynamelookup4 + atf_add_test_case hostsbynamelookup6 + atf_add_test_case hostsbyaddrlookup4 + atf_add_test_case hostsbyaddrlookup6 + + atf_add_test_case dnsbynamelookup4 + atf_add_test_case dnsbynamelookup6 + atf_add_test_case dnsbyaddrlookup4 + atf_add_test_case dnsbyaddrlookup6 +}