Blame tests/test_gethostby_name_addr.c

Packit ac4610
#include "config.h"
Packit ac4610
Packit ac4610
#include <pthread.h>
Packit ac4610
Packit ac4610
#include <stdarg.h>
Packit ac4610
#include <stddef.h>
Packit ac4610
#include <setjmp.h>
Packit ac4610
#include <cmocka.h>
Packit ac4610
Packit ac4610
#include <errno.h>
Packit ac4610
#include <stdio.h>
Packit ac4610
#include <string.h>
Packit ac4610
#include <stdlib.h>
Packit ac4610
#include <unistd.h>
Packit ac4610
Packit ac4610
#include <sys/socket.h>
Packit ac4610
#include <netinet/in.h>
Packit ac4610
#include <arpa/inet.h>
Packit ac4610
#include <netdb.h>
Packit ac4610
Packit ac4610
#define NSS_WRAPPER_HOSTNAME_ENV "NSS_WRAPPER_HOSTNAME"
Packit ac4610
Packit ac4610
static void test_nwrap_gethostname(void **state)
Packit ac4610
{
Packit ac4610
	const char *hostname = "milliways";
Packit ac4610
	char sys_host[256] = {0};
Packit ac4610
	char host[16] = {0};
Packit ac4610
	int rc;
Packit ac4610
Packit ac4610
	(void) state; /* unused */
Packit ac4610
Packit ac4610
	rc = setenv(NSS_WRAPPER_HOSTNAME_ENV, hostname, 1);
Packit ac4610
	assert_int_equal(rc, 0);
Packit ac4610
Packit ac4610
	rc = gethostname(host, sizeof(host));
Packit ac4610
	assert_int_equal(rc, 0);
Packit ac4610
Packit ac4610
	assert_string_equal(host, hostname);
Packit ac4610
Packit ac4610
	rc = setenv(NSS_WRAPPER_HOSTNAME_ENV, "this_hostname_is_too_long", 1);
Packit ac4610
	assert_int_equal(rc, 0);
Packit ac4610
Packit ac4610
	rc = gethostname(host, sizeof(host));
Packit ac4610
	assert_int_equal(rc, -1);
Packit ac4610
	assert_int_equal(errno, ENAMETOOLONG);
Packit ac4610
Packit ac4610
	unsetenv(NSS_WRAPPER_HOSTNAME_ENV);
Packit ac4610
Packit ac4610
	rc = gethostname(sys_host, sizeof(sys_host));
Packit ac4610
	assert_int_equal(rc, 0);
Packit ac4610
Packit ac4610
}
Packit ac4610
Packit ac4610
static void *thread_test_gethostbyname(void *u)
Packit ac4610
{
Packit ac4610
	struct hostent *he;
Packit ac4610
Packit ac4610
	(void) u; /* unused */
Packit ac4610
Packit ac4610
	he = gethostbyname("magrathea");
Packit ac4610
	assert_non_null(he);
Packit ac4610
	assert_non_null(he->h_name);
Packit ac4610
	assert_string_equal(he->h_name, "magrathea.galaxy.site");
Packit ac4610
	pthread_exit(NULL);
Packit ac4610
}
Packit ac4610
Packit ac4610
static void test_nwrap_gethostbyname_thread(void **state)
Packit ac4610
{
Packit ac4610
	struct hostent *he;
Packit ac4610
	pthread_t th;
Packit ac4610
Packit ac4610
	(void) state; /* unused */
Packit ac4610
Packit ac4610
	he = gethostbyname("maximegalon.galaxy.site");
Packit ac4610
	assert_non_null(he);
Packit ac4610
	assert_non_null(he->h_name);
Packit ac4610
	assert_string_equal(he->h_name, "maximegalon.galaxy.site");
Packit ac4610
Packit ac4610
	pthread_create(&th, NULL, &thread_test_gethostbyname, NULL);
Packit ac4610
	pthread_join(th, NULL);
Packit ac4610
Packit ac4610
	assert_non_null(he);
Packit ac4610
	assert_non_null(he->h_name);
Packit ac4610
#ifdef BSD
Packit ac4610
	/*
Packit ac4610
	 * On *BSD (and Mac OS X) systems,
Packit ac4610
	 * data is stored in thread local storage.
Packit ac4610
	 */
Packit ac4610
	assert_string_equal(he->h_name, "maximegalon.galaxy.site");
Packit ac4610
#else
Packit ac4610
	/*
Packit ac4610
	 * Glibc doesn't store data in thread local storage, so calling
Packit ac4610
	 * gethostbyname from a thread overwrites the parent thread's data.
Packit ac4610
	 */
Packit ac4610
	assert_string_equal(he->h_name, "magrathea.galaxy.site");
Packit ac4610
#endif
Packit ac4610
}
Packit ac4610
Packit ac4610
static void test_nwrap_gethostbyname(void **state)
Packit ac4610
{
Packit ac4610
	char ip[INET_ADDRSTRLEN];
Packit ac4610
	struct hostent *he;
Packit ac4610
	const char *a;
Packit ac4610
Packit ac4610
	(void) state; /* unused */
Packit ac4610
Packit ac4610
	he = gethostbyname("magrathea.galaxy.site");
Packit ac4610
	assert_non_null(he);
Packit ac4610
	assert_non_null(he->h_name);
Packit ac4610
	assert_non_null(he->h_addr_list);
Packit ac4610
Packit ac4610
	assert_string_equal(he->h_name, "magrathea.galaxy.site");
Packit ac4610
	assert_int_equal(he->h_addrtype, AF_INET);
Packit ac4610
Packit ac4610
	a = inet_ntop(AF_INET, he->h_addr_list[0], ip, sizeof(ip));
Packit ac4610
	assert_non_null(a);
Packit ac4610
Packit ac4610
	assert_string_equal(ip, "127.0.0.11");
Packit ac4610
}
Packit ac4610
Packit ac4610
static void test_nwrap_gethostbyname_multiple(void **state)
Packit ac4610
{
Packit ac4610
	struct hostent *he;
Packit ac4610
	char **list;
Packit ac4610
Packit ac4610
	/* For inet_ntop call */
Packit ac4610
	char buf[4096];
Packit ac4610
	const char *result;
Packit ac4610
	char *p = buf;
Packit ac4610
Packit ac4610
	/* List of ips in hosts file - order matters */
Packit ac4610
	const char *const result_ips[] = { "127.0.0.11", "127.0.0.12", NULL };
Packit ac4610
	const char *actual_ip = result_ips[0];
Packit ac4610
	unsigned int ac;
Packit ac4610
Packit ac4610
	(void) state; /* unused */
Packit ac4610
Packit ac4610
	he = gethostbyname("magrathea.galaxy.site");
Packit ac4610
	assert_non_null(he);
Packit ac4610
	assert_non_null(he->h_name);
Packit ac4610
	assert_non_null(he->h_addr_list);
Packit ac4610
Packit ac4610
	list = he->h_addr_list;
Packit ac4610
	for (ac = 0; *list != NULL; ++ac, ++list) {
Packit ac4610
		actual_ip = result_ips[ac];
Packit ac4610
		/* When test fails here more records are returned */
Packit ac4610
		assert_non_null(actual_ip);
Packit ac4610
		result = inet_ntop(AF_INET, *list, p, 4096);
Packit ac4610
		assert_non_null(p);
Packit ac4610
		assert_string_equal(actual_ip, result);
Packit ac4610
	}
Packit ac4610
}
Packit ac4610
Packit ac4610
#ifdef HAVE_GETHOSTBYNAME2
Packit ac4610
static void test_nwrap_gethostbyname2(void **state)
Packit ac4610
{
Packit ac4610
	char ip[INET6_ADDRSTRLEN];
Packit ac4610
	struct hostent *he;
Packit ac4610
	const char *a;
Packit ac4610
Packit ac4610
	(void) state; /* unused */
Packit ac4610
Packit ac4610
	he = gethostbyname2("magrathea.galaxy.site", AF_INET6);
Packit ac4610
	assert_non_null(he);
Packit ac4610
Packit ac4610
	he = gethostbyname2("magrathea.galaxy.site", AF_INET);
Packit ac4610
	assert_non_null(he);
Packit ac4610
Packit ac4610
	/* Check ipv6 he */
Packit ac4610
	he = gethostbyname2("krikkit.galaxy.site", AF_INET6);
Packit ac4610
	assert_non_null(he);
Packit ac4610
	assert_non_null(he->h_name);
Packit ac4610
	assert_non_null(he->h_addr_list);
Packit ac4610
Packit ac4610
	assert_string_equal(he->h_name, "krikkit.galaxy.site");
Packit ac4610
	assert_int_equal(he->h_addrtype, AF_INET6);
Packit ac4610
Packit ac4610
	a = inet_ntop(AF_INET6, he->h_addr_list[0], ip, sizeof(ip));
Packit ac4610
	assert_non_null(a);
Packit ac4610
Packit ac4610
	assert_string_equal(ip, "::14");
Packit ac4610
Packit ac4610
	/* Check ipv4 he */
Packit ac4610
	he = gethostbyname2("krikkit.galaxy.site", AF_INET);
Packit ac4610
	assert_non_null(he);
Packit ac4610
	assert_non_null(he->h_name);
Packit ac4610
	assert_non_null(he->h_addr_list);
Packit ac4610
Packit ac4610
	assert_string_equal(he->h_name, "krikkit.galaxy.site");
Packit ac4610
	assert_int_equal(he->h_addrtype, AF_INET);
Packit ac4610
Packit ac4610
	a = inet_ntop(AF_INET, he->h_addr_list[0], ip, sizeof(ip));
Packit ac4610
	assert_non_null(a);
Packit ac4610
Packit ac4610
	assert_string_equal(ip, "127.0.0.14");
Packit ac4610
}
Packit ac4610
#endif /* HAVE_GETHOSTBYNAME2 */
Packit ac4610
Packit ac4610
static void test_nwrap_gethostbyaddr(void **state)
Packit ac4610
{
Packit ac4610
	struct hostent *he;
Packit ac4610
	struct in_addr in;
Packit ac4610
	int rc;
Packit ac4610
Packit ac4610
	(void) state; /* unused */
Packit ac4610
Packit ac4610
	rc = inet_aton("127.0.0.11", &in);
Packit ac4610
	assert_int_equal(rc, 1);
Packit ac4610
Packit ac4610
	he = gethostbyaddr(&in, sizeof(struct in_addr), AF_INET);
Packit ac4610
	assert_non_null(he);
Packit ac4610
	assert_non_null(he->h_name);
Packit ac4610
	assert_non_null(he->h_addr_list);
Packit ac4610
Packit ac4610
	assert_string_equal(he->h_name, "magrathea.galaxy.site");
Packit ac4610
	assert_int_equal(he->h_addrtype, AF_INET);
Packit ac4610
	assert_memory_equal(&in, he->h_addr_list[0], he->h_length);
Packit ac4610
}
Packit ac4610
Packit ac4610
#ifdef HAVE_GETHOSTBYNAME_R
Packit ac4610
static void test_nwrap_gethostbyname_r(void **state)
Packit ac4610
{
Packit ac4610
	char buf[1024] = {0};
Packit ac4610
	char ip[INET_ADDRSTRLEN];
Packit ac4610
	struct hostent hb, *he;
Packit ac4610
	const char *a;
Packit ac4610
	int herr = 0;
Packit ac4610
	int rc;
Packit ac4610
Packit ac4610
	(void) state; /* unused */
Packit ac4610
Packit ac4610
	rc = gethostbyname_r("magrathea.galaxy.site",
Packit ac4610
			     &hb,
Packit ac4610
			     buf, sizeof(buf),
Packit ac4610
			     &he,
Packit ac4610
			     &herr;;
Packit ac4610
	assert_int_equal(rc, 0);
Packit ac4610
	assert_non_null(he);
Packit ac4610
	assert_non_null(he->h_name);
Packit ac4610
	assert_non_null(he->h_addr_list);
Packit ac4610
Packit ac4610
	assert_string_equal(he->h_name, "magrathea.galaxy.site");
Packit ac4610
	assert_int_equal(he->h_addrtype, AF_INET);
Packit ac4610
Packit ac4610
	a = inet_ntop(AF_INET, he->h_addr_list[0], ip, sizeof(ip));
Packit ac4610
	assert_non_null(a);
Packit ac4610
Packit ac4610
	assert_string_equal(ip, "127.0.0.11");
Packit ac4610
}
Packit ac4610
#endif
Packit ac4610
Packit ac4610
#ifdef HAVE_GETHOSTBYADDR_R
Packit ac4610
static void test_nwrap_gethostbyaddr_r(void **state)
Packit ac4610
{
Packit ac4610
	char buf[1024] = {0};
Packit ac4610
	struct hostent hb, *he;
Packit ac4610
	struct in_addr in;
Packit ac4610
	int herr = 0;
Packit ac4610
	int rc;
Packit ac4610
Packit ac4610
	(void) state; /* unused */
Packit ac4610
Packit ac4610
	rc = inet_aton("127.0.0.11", &in);
Packit ac4610
	assert_int_equal(rc, 1);
Packit ac4610
Packit ac4610
	rc = gethostbyaddr_r(&in, sizeof(struct in_addr),
Packit ac4610
			     AF_INET,
Packit ac4610
			     &hb,
Packit ac4610
			     buf, sizeof(buf),
Packit ac4610
			     &he,
Packit ac4610
			     &herr;;
Packit ac4610
	assert_int_equal(rc, 0);
Packit ac4610
	assert_non_null(he);
Packit ac4610
	assert_non_null(he->h_name);
Packit ac4610
	assert_non_null(he->h_addr_list);
Packit ac4610
Packit ac4610
	assert_string_equal(he->h_name, "magrathea.galaxy.site");
Packit ac4610
	assert_int_equal(he->h_addrtype, AF_INET);
Packit ac4610
	assert_memory_equal(&in, he->h_addr_list[0], he->h_length);
Packit ac4610
}
Packit ac4610
#endif
Packit ac4610
Packit ac4610
int main(void) {
Packit ac4610
	int rc;
Packit ac4610
Packit ac4610
	const struct CMUnitTest tests[] = {
Packit ac4610
		cmocka_unit_test(test_nwrap_gethostname),
Packit ac4610
		cmocka_unit_test(test_nwrap_gethostbyname),
Packit ac4610
		cmocka_unit_test(test_nwrap_gethostbyname_thread),
Packit ac4610
#ifdef HAVE_GETHOSTBYNAME2
Packit ac4610
		cmocka_unit_test(test_nwrap_gethostbyname2),
Packit ac4610
#endif
Packit ac4610
		cmocka_unit_test(test_nwrap_gethostbyaddr),
Packit ac4610
#ifdef HAVE_GETHOSTBYNAME_R
Packit ac4610
		cmocka_unit_test(test_nwrap_gethostbyname_r),
Packit ac4610
#endif
Packit ac4610
#ifdef HAVE_GETHOSTBYADDR_R
Packit ac4610
		cmocka_unit_test(test_nwrap_gethostbyaddr_r),
Packit ac4610
#endif
Packit ac4610
		cmocka_unit_test(test_nwrap_gethostbyname_multiple),
Packit ac4610
	};
Packit ac4610
Packit ac4610
	rc = cmocka_run_group_tests(tests, NULL, NULL);
Packit ac4610
Packit ac4610
	return rc;
Packit ac4610
}
Packit ac4610