summaryrefslogtreecommitdiff
path: root/src/tests/resolve
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/resolve')
-rw-r--r--src/tests/resolve/Makefile.in28
-rw-r--r--src/tests/resolve/addrinfo-test.c306
-rw-r--r--src/tests/resolve/deps13
-rw-r--r--src/tests/resolve/fake-addrinfo-test.c3
-rw-r--r--src/tests/resolve/resolve.c161
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);
+
+}