13 #include <netinet/in.h>
14 #include <arpa/nameser.h>
15 #include <arpa/inet.h>
18 #define RWRAP_RESOLV_CONF_TMPL "rwrap_resolv_conf_XXXXXX"
20 struct resolv_conf_test_state {
23 char *resolv_conf_path;
26 static int setup(void **state)
28 struct resolv_conf_test_state *test_state;
30 test_state = malloc(sizeof(struct resolv_conf_test_state));
31 assert_non_null(test_state);
32 test_state->rc_fd = -1;
33 test_state->resolv_conf = NULL;
35 test_state->resolv_conf_path = strdup(RWRAP_RESOLV_CONF_TMPL);
36 assert_non_null(test_state->resolv_conf_path);
37 test_state->rc_fd = mkstemp(test_state->resolv_conf_path);
38 assert_non_null(test_state->resolv_conf_path);
39 test_state->resolv_conf = fdopen(test_state->rc_fd, "a");
40 assert_non_null(test_state->resolv_conf);
47 static int teardown(void **state)
49 struct resolv_conf_test_state *test_state;
51 test_state = (struct resolv_conf_test_state *) *state;
53 if (test_state == NULL) return -1;
55 if (test_state->resolv_conf) {
56 fclose(test_state->resolv_conf);
59 if (test_state->rc_fd != -1) {
60 close(test_state->rc_fd);
63 if (test_state->resolv_conf_path) {
64 unlink(test_state->resolv_conf_path);
65 free(test_state->resolv_conf_path);
73 static void test_res_ninit(void **state)
75 struct resolv_conf_test_state *test_state;
76 struct __res_state dnsstate;
78 * libc resolver only supports 3 name servers. Make sure the
79 * extra are skipped for both v4 and v6. Also make sure there's
80 * 'too many' nameservers even on platforms where v6 is not
83 const char *nameservers[] = {
86 "fd53:53:53:53::1011",
89 "fd53:53:53:53::1012",
94 char straddr[INET6_ADDRSTRLEN] = { '\0' };
95 #ifdef HAVE_RESOLV_IPV6_NSADDRS
96 struct sockaddr_in6 *sa6;
99 test_state = (struct resolv_conf_test_state *) *state;
102 * Write a valid resolv.conf.
103 * Make sure it's possible to skip comments
105 fputs("# Hello world\n", test_state->resolv_conf);
106 fputs("; This is resolv_wrapper\n", test_state->resolv_conf);
107 for (i = 0; nameservers[i]; i++) {
108 fputs("nameserver ", test_state->resolv_conf);
109 fputs(nameservers[i], test_state->resolv_conf);
110 fputs("\n", test_state->resolv_conf);
112 fflush(test_state->resolv_conf);
114 rv = setenv("RESOLV_WRAPPER_CONF", test_state->resolv_conf_path, 1);
115 assert_int_equal(rv, 0);
117 memset(&dnsstate, 0, sizeof(dnsstate));
118 rv = res_ninit(&dnsstate);
119 unsetenv("RESOLV_WRAPPER_CONF");
120 assert_int_equal(rv, 0);
123 * Validate the number of parsed name servers.
126 assert_int_equal(dnsstate.nscount + dnsstate._u._ext.nscount, MAXNS);
128 #ifndef HAVE_RESOLV_IPV6_NSADDRS
130 * On platforms that don't support IPv6, the v6 address is skipped
131 * and we end up reading three v4 addresses.
133 assert_int_equal(dnsstate.nscount, MAXNS);
136 * test we have two v4 and one v6 server
138 * Note: This test assumes MAXNS == 3, which is the
139 * case on all systems encountered so far.
141 assert_int_equal(dnsstate.nscount, 2);
142 assert_int_equal(dnsstate._u._ext.nscount, 1);
143 #endif /* HAVE_RESOLV_IPV6_NSADDRS */
145 /* Validate the servers. */
148 assert_int_equal(dnsstate.nsaddr_list[0].sin_family, AF_INET);
149 assert_int_equal(dnsstate.nsaddr_list[0].sin_port, htons(53));
150 inet_ntop(AF_INET, &(dnsstate.nsaddr_list[0].sin_addr),
151 straddr, INET6_ADDRSTRLEN);
152 assert_string_equal(nameservers[0], straddr);
154 assert_int_equal(dnsstate.nsaddr_list[1].sin_family, AF_INET);
155 assert_int_equal(dnsstate.nsaddr_list[1].sin_port, htons(53));
156 inet_ntop(AF_INET, &(dnsstate.nsaddr_list[1].sin_addr),
157 straddr, INET6_ADDRSTRLEN);
158 assert_string_equal(nameservers[1], straddr);
160 #ifndef HAVE_RESOLV_IPV6_NSADDRS
162 * On platforms that don't support IPv6, the v6 address is skipped
163 * and we end up reading three v4 addresses.
165 assert_int_equal(dnsstate.nsaddr_list[2].sin_family, AF_INET);
166 assert_int_equal(dnsstate.nsaddr_list[2].sin_port, htons(53));
167 inet_ntop(AF_INET, &(dnsstate.nsaddr_list[2].sin_addr),
168 straddr, INET6_ADDRSTRLEN);
169 assert_string_equal(nameservers[3], straddr);
172 sa6 = dnsstate._u._ext.nsaddrs[0];
173 assert_int_equal(sa6->sin6_family, AF_INET6);
174 assert_int_equal(sa6->sin6_port, htons(53));
175 inet_ntop(AF_INET6, &(sa6->sin6_addr), straddr, INET6_ADDRSTRLEN);
176 assert_string_equal(nameservers[2], straddr);
179 res_nclose(&dnsstate);
182 static void test_res_ninit_enoent(void **state)
185 struct __res_state dnsstate;
187 (void) state; /* unused */
189 rv = setenv("RESOLV_WRAPPER_CONF", "/no/such/file", 1);
190 assert_int_equal(rv, 0);
192 /* Just make sure we don't crash, error is fine */
193 memset(&dnsstate, 0, sizeof(dnsstate));
194 rv = res_ninit(&dnsstate);
195 unsetenv("RESOLV_WRAPPER_CONF");
196 assert_int_equal(rv, -1);
202 const struct CMUnitTest init_tests[] = {
203 cmocka_unit_test_setup_teardown(test_res_ninit, setup, teardown),
204 cmocka_unit_test(test_res_ninit_enoent),
207 rc = cmocka_run_group_tests(init_tests, NULL, NULL);