diff options
Diffstat (limited to 'src/tests/resolve')
| -rw-r--r-- | src/tests/resolve/Makefile.in | 28 | ||||
| -rw-r--r-- | src/tests/resolve/addrinfo-test.c | 306 | ||||
| -rw-r--r-- | src/tests/resolve/deps | 13 | ||||
| -rw-r--r-- | src/tests/resolve/fake-addrinfo-test.c | 3 | ||||
| -rw-r--r-- | src/tests/resolve/resolve.c | 161 |
5 files changed, 511 insertions, 0 deletions
diff --git a/src/tests/resolve/Makefile.in b/src/tests/resolve/Makefile.in new file mode 100644 index 000000000000..e6248f814b6a --- /dev/null +++ b/src/tests/resolve/Makefile.in @@ -0,0 +1,28 @@ +mydir=tests$(S)resolve +BUILDTOP=$(REL)..$(S).. + +OBJS=resolve.o addrinfo-test.o fake-addrinfo-test.o +SRCS=$(srcdir)/resolve.c $(srcdir)/addrinfo-test.c \ + $(srcdir)/fake-addrinfo-test.c + +all: resolve addrinfo-test fake-addrinfo-test + +resolve: resolve.o + $(CC_LINK) -o $@ resolve.o $(LIBS) + +addrinfo-test: addrinfo-test.o + $(CC_LINK) -o $@ addrinfo-test.o $(SUPPORT_LIB) $(LIBS) + +fake-addrinfo-test: fake-addrinfo-test.o + $(CC_LINK) -o $@ fake-addrinfo-test.o $(SUPPORT_LIB) $(LIBS) + +check: resolve addrinfo-test fake-addrinfo-test + $(RUN_TEST) ./resolve + $(RUN_TEST) ./addrinfo-test -p telnet + $(RUN_TEST) ./fake-addrinfo-test -p telnet + +install: + +clean: + $(RM) resolve addrinfo-test fake-addrinfo-test + diff --git a/src/tests/resolve/addrinfo-test.c b/src/tests/resolve/addrinfo-test.c new file mode 100644 index 000000000000..e77640b62f9b --- /dev/null +++ b/src/tests/resolve/addrinfo-test.c @@ -0,0 +1,306 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* tests/resolve/addrinfo-test.c */ +/* + * Copyright 2004 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +/* + * A simple program to test the functionality of the getaddrinfo function. + * + * Usage: + * addrinfo-test [-t|-u|-R|-I] [-d|-s|-r] [-p port] [-P] [hostname] + * + * When invoked with no arguments, NULL is used for the node name, + * which (at least with a non-null "port") means a socket address + * is desired that can be used with connect() or bind() (depending + * on whether "-P" is given). + */ + +#include <k5-platform.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> +#include <netinet/in.h> /* needed for IPPROTO_* on NetBSD */ +#ifdef USE_FAKE_ADDRINFO +#include "fake-addrinfo.h" +#endif + +static const char *protoname (int p) { + static char buf[30]; + +#define X(N) if (p == IPPROTO_ ## N) return #N + + X(TCP); + X(UDP); + X(ICMP); +#ifdef IPPROTO_IPV6 + X(IPV6); +#endif +#ifdef IPPROTO_GRE + X(GRE); +#endif +#ifdef IPPROTO_NONE + X(NONE); +#endif + X(RAW); +#ifdef IPPROTO_COMP + X(COMP); +#endif + + snprintf(buf, sizeof(buf), " %-2d", p); + return buf; +} + +static const char *socktypename (int t) { + static char buf[30]; + switch (t) { + case SOCK_DGRAM: return "DGRAM"; + case SOCK_STREAM: return "STREAM"; + case SOCK_RAW: return "RAW"; + case SOCK_RDM: return "RDM"; + case SOCK_SEQPACKET: return "SEQPACKET"; + } + snprintf(buf, sizeof(buf), " %-2d", t); + return buf; +} + +static char *whoami; + +static void usage () { + fprintf(stderr, + "usage:\n" + "\t%s [ options ] [host]\n" + "options:\n" + "\t-t\tspecify protocol IPPROTO_TCP\n" + "\t-u\tspecify protocol IPPROTO_UDP\n" + "\t-R\tspecify protocol IPPROTO_RAW\n" + "\t-I\tspecify protocol IPPROTO_ICMP\n" + "\n" + "\t-d\tspecify socket type SOCK_DGRAM\n" + "\t-s\tspecify socket type SOCK_STREAM\n" + "\t-r\tspecify socket type SOCK_RAW\n" + "\n" + "\t-4\tspecify address family AF_INET\n" +#ifdef AF_INET6 + "\t-6\tspecify address family AF_INET6\n" +#endif + "\n" + "\t-p P\tspecify port P (service name or port number)\n" + "\t-N\thostname is numeric, skip DNS query\n" + "\t-n\tservice/port is numeric (sets AI_NUMERICSERV)\n" + "\t-P\tset AI_PASSIVE\n" + "\n" + "default: protocol 0, socket type 0, address family 0, null port\n" + , + whoami); + /* [ -t | -u | -R | -I ] [ -d | -s | -r ] [ -p port ] */ + exit (1); +} + +static const char *familyname (int f) { + static char buf[30]; + switch (f) { + default: + snprintf(buf, sizeof(buf), "AF %d", f); + return buf; + case AF_INET: return "AF_INET"; +#ifdef AF_INET6 + case AF_INET6: return "AF_INET6"; +#endif + } +} + +#define eaistr(X) (X == EAI_SYSTEM ? strerror(errno) : gai_strerror(X)) + +int main (int argc, char *argv[]) +{ + struct addrinfo *ap, *ap2; + int err, numerichost = 0, numericserv = 0; + char *hname, *port = 0, *sep; + struct addrinfo hints; + + whoami = strrchr(argv[0], '/'); + if (whoami == 0) + whoami = argv[0]; + else + whoami = whoami+1; + + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = 0; + hints.ai_socktype = 0; + + hname = 0; + hints.ai_family = 0; + + if (argc == 1) + usage (); + + while (++argv, --argc > 0) { + char *arg; + arg = *argv; + + if (*arg != '-') + hname = arg; + else if (arg[1] == 0 || arg[2] != 0) + usage (); + else + switch (arg[1]) { + case 'u': + hints.ai_protocol = IPPROTO_UDP; + break; + case 't': + hints.ai_protocol = IPPROTO_TCP; + break; + case 'R': + hints.ai_protocol = IPPROTO_RAW; + break; + case 'I': + hints.ai_protocol = IPPROTO_ICMP; + break; + case 'd': + hints.ai_socktype = SOCK_DGRAM; + break; + case 's': + hints.ai_socktype = SOCK_STREAM; + break; + case 'r': + hints.ai_socktype = SOCK_RAW; + break; + case 'p': + if (argv[1] == 0 || argv[1][0] == 0 || argv[1][0] == '-') + usage (); + port = argv[1]; + argc--, argv++; + break; + case '4': + hints.ai_family = AF_INET; + break; +#ifdef AF_INET6 + case '6': + hints.ai_family = AF_INET6; + break; +#endif + case 'N': + numerichost = 1; + break; + case 'n': + numericserv = 1; + break; + case 'P': + hints.ai_flags |= AI_PASSIVE; + break; + default: + usage (); + } + } + + if (hname && !numerichost) + hints.ai_flags |= AI_CANONNAME; + if (numerichost) { +#ifdef AI_NUMERICHOST + hints.ai_flags |= AI_NUMERICHOST; +#else + fprintf(stderr, "AI_NUMERICHOST not defined on this platform\n"); + exit(1); +#endif + } + if (numericserv) { +#ifdef AI_NUMERICSERV + hints.ai_flags |= AI_NUMERICSERV; +#else + fprintf(stderr, "AI_NUMERICSERV not defined on this platform\n"); + exit(1); +#endif + } + + printf("getaddrinfo(hostname %s, service %s,\n" + " hints { ", + hname ? hname : "(null)", port ? port : "(null)"); + sep = ""; +#define Z(FLAG) if (hints.ai_flags & AI_##FLAG) printf("%s%s", sep, #FLAG), sep = "|" + Z(CANONNAME); + Z(PASSIVE); +#ifdef AI_NUMERICHOST + Z(NUMERICHOST); +#endif +#ifdef AI_NUMERICSERV + Z(NUMERICSERV); +#endif + if (sep[0] == 0) + printf ("no-flags"); + if (hints.ai_family) + printf(" %s", familyname(hints.ai_family)); + if (hints.ai_socktype) + printf(" SOCK_%s", socktypename(hints.ai_socktype)); + if (hints.ai_protocol) + printf(" IPPROTO_%s", protoname(hints.ai_protocol)); + printf(" }):\n"); + + err = getaddrinfo(hname, port, &hints, &ap); + if (err) { + printf("\terror => %s\n", eaistr(err)); + return 1; + } + + for (ap2 = ap; ap2; ap2 = ap2->ai_next) { + char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV]; + /* If we don't do this, even AIX's own getnameinfo will reject + the sockaddr structures. The sa_len field doesn't get set + either, on AIX, but getnameinfo won't complain. */ + if (ap2->ai_addr->sa_family == 0) { + printf("BAD: sa_family zero! fixing...\n"); + ap2->ai_addr->sa_family = ap2->ai_family; + } else if (ap2->ai_addr->sa_family != ap2->ai_family) { + printf("BAD: sa_family != ai_family! fixing...\n"); + ap2->ai_addr->sa_family = ap2->ai_family; + } + if (getnameinfo(ap2->ai_addr, ap2->ai_addrlen, hbuf, sizeof(hbuf), + pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV)) { + strlcpy(hbuf, "...", sizeof(hbuf)); + strlcpy(pbuf, "...", sizeof(pbuf)); + } + printf("%p:\n" + "\tfamily = %s\tproto = %-4s\tsocktype = %s\n", + (void *) ap2, familyname(ap2->ai_family), + protoname (ap2->ai_protocol), + socktypename (ap2->ai_socktype)); + if (ap2->ai_canonname) { + if (ap2->ai_canonname[0]) + printf("\tcanonname = %s\n", ap2->ai_canonname); + else + printf("BAD: ai_canonname is set but empty!\n"); + } else if (ap2 == ap && (hints.ai_flags & AI_CANONNAME)) { + printf("BAD: first ai_canonname is null!\n"); + } + printf("\taddr = %-28s\tport = %s\n", hbuf, pbuf); + + err = getnameinfo(ap2->ai_addr, ap2->ai_addrlen, hbuf, sizeof (hbuf), + pbuf, sizeof(pbuf), NI_NAMEREQD); + if (err) + printf("\tgetnameinfo(NI_NAMEREQD): %s\n", eaistr(err)); + else + printf("\tgetnameinfo => %s, %s\n", hbuf, pbuf); + } + freeaddrinfo(ap); + return 0; +} diff --git a/src/tests/resolve/deps b/src/tests/resolve/deps new file mode 100644 index 000000000000..158110682d0a --- /dev/null +++ b/src/tests/resolve/deps @@ -0,0 +1,13 @@ +# +# Generated makefile dependencies follow. +# +$(OUTPRE)resolve.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + resolve.c +$(OUTPRE)addrinfo-test.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ + addrinfo-test.c +$(OUTPRE)fake-addrinfo-test.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(top_srcdir)/include/fake-addrinfo.h $(top_srcdir)/include/k5-platform.h \ + $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/port-sockets.h \ + $(top_srcdir)/include/socket-utils.h addrinfo-test.c \ + fake-addrinfo-test.c diff --git a/src/tests/resolve/fake-addrinfo-test.c b/src/tests/resolve/fake-addrinfo-test.c new file mode 100644 index 000000000000..86365a5baf33 --- /dev/null +++ b/src/tests/resolve/fake-addrinfo-test.c @@ -0,0 +1,3 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +#define USE_FAKE_ADDRINFO +#include "addrinfo-test.c" diff --git a/src/tests/resolve/resolve.c b/src/tests/resolve/resolve.c new file mode 100644 index 000000000000..7339d21bd9ac --- /dev/null +++ b/src/tests/resolve/resolve.c @@ -0,0 +1,161 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* tests/resolve/resolve.c */ +/* + * Copyright 1995 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +/* + * A simple program to test the functionality of the resolver library. + * It simply will try to get the IP address of the host, and then look + * up the name from the address. If the resulting name does not contain the + * domain name, then the resolve library is broken. + * + * Warning: It is possible to fool this program into thinking everything is + * alright by a clever use of /etc/hosts - but this is better than nothing. + * + * Usage: + * resolve [hostname] + * + * When invoked with no arguments, gethostname is used for the local host. + * + */ + +/* This program tests the resolve library and sees if it is broken... */ + +#include "autoconf.h" +#include <stdio.h> + +#if STDC_HEADERS +#include <string.h> +#else +#ifndef HAVE_STRCHR +#define strchr index +#endif +char *strchr(); +#endif + +#ifdef HAVE_SYS_PARAM_H +#include <sys/param.h> +#endif + +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif + +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include <netinet/in.h> +#include <netdb.h> + +int +main(argc, argv) + int argc; + char **argv; +{ + char myname[MAXHOSTNAMELEN+1]; + char *ptr, *fqdn; + struct in_addr addrcopy; + struct hostent *host; + int quiet = 0; + + argc--; argv++; + while (argc) { + if ((strcmp(*argv, "--quiet") == 0) || + (strcmp(*argv, "-q") == 0)) { + quiet++; + } else + break; + argc--; argv++; + } + + if (argc >= 1) { + strncpy(myname, *argv, MAXHOSTNAMELEN); + } else { + if(gethostname(myname, MAXHOSTNAMELEN)) { + perror("gethostname failure"); + exit(1); + } + } + + myname[MAXHOSTNAMELEN] = '\0'; /* for safety */ + + /* Look up the address... */ + if (!quiet) + printf("Hostname: %s\n", myname); + + + /* Set the hosts db to close each time - effectively rewinding file */ + sethostent(0); + + if((host = gethostbyname (myname)) == NULL) { + fprintf(stderr, + "Could not look up address for hostname '%s' - fatal\n", + myname); + exit(2); + } + + fqdn = strdup(host->h_name); + if (fqdn == NULL) { + perror("strdup"); + exit(2); + } + + ptr = host->h_addr_list[0]; +#define UC(a) (((int)a)&0xff) + if (!quiet) + printf("Host address: %d.%d.%d.%d\n", + UC(ptr[0]), UC(ptr[1]), UC(ptr[2]), UC(ptr[3])); + + memcpy(&addrcopy.s_addr, ptr, 4); + + /* Convert back to full name */ + if ((host = gethostbyaddr(&addrcopy.s_addr, 4, AF_INET)) == NULL) { + if (!quiet) + fprintf(stderr, "Error looking up IP address\n"); + } else { + free(fqdn); + fqdn = strdup(host->h_name); + if (fqdn == NULL) { + perror("strdup"); + exit (2); + } + } + + if (quiet) + printf("%s\n", fqdn); + else + printf("FQDN: %s\n", fqdn); + + if (!quiet) + printf("Resolve library appears to have passed the test\n"); + + /* All ok */ + exit(0); + +} |
