1 #include "config.h"
2 
3 #include <stdarg.h>
4 #include <stddef.h>
5 #include <setjmp.h>
6 #include <cmocka.h>
7 
8 #include <stdio.h>
9 #include <string.h>
10 #include <unistd.h>
11 
12 #include <sys/socket.h>
13 #include <netinet/in.h>
14 #include <arpa/inet.h>
15 #include <netdb.h>
16 
test_nwrap_getnameinfo(void ** state)17 static void test_nwrap_getnameinfo(void **state)
18 {
19 	char host[256] = {0};
20 	char serv[256] = {0};
21 	struct sockaddr_in sin;
22 	struct sockaddr_in6 sin6;
23 	int flags = 0;
24 	int rc;
25 
26 	(void) state; /* unused */
27 
28 	/* IPv4 */
29 	sin.sin_family = AF_INET;
30 	sin.sin_port = htons(53);
31 	rc = inet_pton(AF_INET, "127.0.0.11", &sin.sin_addr);
32 	assert_int_equal(rc, 1);
33 
34 	rc = getnameinfo((const struct sockaddr *)&sin,
35 			 sizeof(struct sockaddr_in),
36 			 host, sizeof(host),
37 			 serv, sizeof(serv),
38 			 flags);
39 	assert_int_equal(rc, 0);
40 
41 	assert_string_equal(host, "magrathea.galaxy.site");
42 	assert_string_equal(serv, "domain");
43 
44 	/* IPv6 */
45 	sin6.sin6_family = AF_INET6;
46 	sin6.sin6_port = htons(53);
47 	rc = inet_pton(AF_INET6, "::13", &sin6.sin6_addr);
48 	assert_int_equal(rc, 1);
49 
50 	rc = getnameinfo((const struct sockaddr *)&sin6,
51 			 sizeof(struct sockaddr_in6),
52 			 host, sizeof(host),
53 			 serv, sizeof(serv),
54 			 flags);
55 	assert_int_equal(rc, 0);
56 
57 	assert_string_equal(host, "beteigeuze.galaxy.site");
58 	assert_string_equal(serv, "domain");
59 }
60 
test_nwrap_getnameinfo_numeric(void ** state)61 static void test_nwrap_getnameinfo_numeric(void **state)
62 {
63 	char host[256] = {0};
64 	char serv[256] = {0};
65 	struct sockaddr_in sin;
66 	struct sockaddr_in6 sin6;
67 	int flags = 0;
68 	int rc;
69 
70 	(void) state; /* unused */
71 
72 	/* IPv4 */
73 	sin.sin_family = AF_INET;
74 	sin.sin_port = htons(53);
75 	rc = inet_pton(AF_INET, "127.0.0.11", &sin.sin_addr);
76 	assert_int_equal(rc, 1);
77 
78 	flags = NI_NUMERICHOST;
79 
80 	rc = getnameinfo((const struct sockaddr *)&sin,
81 			 sizeof(struct sockaddr_in),
82 			 host, sizeof(host),
83 			 serv, sizeof(serv),
84 			 flags);
85 	assert_int_equal(rc, 0);
86 
87 	assert_string_equal(host, "127.0.0.11");
88 	assert_string_equal(serv, "domain");
89 
90 	/* IPv6 */
91 	sin6.sin6_family = AF_INET6;
92 	sin6.sin6_port = htons(53);
93 	rc = inet_pton(AF_INET6, "::13", &sin6.sin6_addr);
94 	assert_int_equal(rc, 1);
95 
96 	flags = NI_NUMERICSERV;
97 
98 	rc = getnameinfo((const struct sockaddr *)&sin6,
99 			 sizeof(struct sockaddr_in6),
100 			 host, sizeof(host),
101 			 serv, sizeof(serv),
102 			 flags);
103 	assert_int_equal(rc, 0);
104 
105 	assert_string_equal(host, "beteigeuze.galaxy.site");
106 	assert_string_equal(serv, "53");
107 }
108 
test_nwrap_getnameinfo_any(void ** state)109 static void test_nwrap_getnameinfo_any(void **state)
110 {
111 	char host[256] = {0};
112 	char serv[256] = {0};
113 	struct sockaddr_in sin;
114 	struct sockaddr_in6 sin6;
115 	int flags = 0;
116 	int rc;
117 
118 	(void) state; /* unused */
119 
120 	/* IPv4 */
121 	sin.sin_family = AF_INET;
122 	sin.sin_port = htons(22);
123 	rc = inet_pton(AF_INET, "0.0.0.0", &sin.sin_addr);
124 	assert_int_equal(rc, 1);
125 
126 	rc = getnameinfo((const struct sockaddr *)&sin,
127 			 sizeof(struct sockaddr_in),
128 			 host, sizeof(host),
129 			 serv, sizeof(serv),
130 			 flags);
131 	assert_int_equal(rc, 0);
132 
133 	assert_string_equal(host, "0.0.0.0");
134 	assert_string_equal(serv, "ssh");
135 
136 	/* IPv6 */
137 	sin6.sin6_family = AF_INET6;
138 	sin6.sin6_port = htons(22);
139 	rc = inet_pton(AF_INET6, "::", &sin6.sin6_addr);
140 	assert_int_equal(rc, 1);
141 
142 	rc = getnameinfo((const struct sockaddr *)&sin6,
143 			 sizeof(struct sockaddr_in6),
144 			 host, sizeof(host),
145 			 serv, sizeof(serv),
146 			 flags);
147 	assert_int_equal(rc, 0);
148 
149 	assert_string_equal(host, "::");
150 	assert_string_equal(serv, "ssh");
151 }
152 
test_nwrap_getnameinfo_local(void ** state)153 static void test_nwrap_getnameinfo_local(void **state)
154 {
155 	char host[256] = {0};
156 	char serv[256] = {0};
157 	struct sockaddr_in sin;
158 	struct sockaddr_in6 sin6;
159 	int flags = 0;
160 	int rc;
161 
162 	(void) state; /* unused */
163 
164 	/* IPv4 */
165 	sin.sin_family = AF_INET;
166 	sin.sin_port = htons(22);
167 	rc = inet_pton(AF_INET, "127.0.0.1", &sin.sin_addr);
168 	assert_int_equal(rc, 1);
169 
170 	rc = getnameinfo((const struct sockaddr *)&sin,
171 			 sizeof(struct sockaddr_in),
172 			 host, sizeof(host),
173 			 serv, sizeof(serv),
174 			 flags);
175 	assert_int_equal(rc, 0);
176 
177 	assert_string_equal(host, "127.0.0.1");
178 	assert_string_equal(serv, "ssh");
179 
180 	/* IPv6 */
181 	sin6.sin6_family = AF_INET6;
182 	sin6.sin6_port = htons(22);
183 	rc = inet_pton(AF_INET6, "::1", &sin6.sin6_addr);
184 	assert_int_equal(rc, 1);
185 
186 	rc = getnameinfo((const struct sockaddr *)&sin6,
187 			 sizeof(struct sockaddr_in6),
188 			 host, sizeof(host),
189 			 serv, sizeof(serv),
190 			 flags);
191 	assert_int_equal(rc, 0);
192 
193 	assert_string_equal(host, "::1");
194 	assert_string_equal(serv, "ssh");
195 }
196 
test_nwrap_getnameinfo_null(void ** state)197 static void test_nwrap_getnameinfo_null(void **state)
198 {
199 	char host[256] = {0};
200 	char serv[256] = {0};
201 	struct sockaddr_in sin;
202 	struct sockaddr_in6 sin6;
203 	int flags = 0;
204 	int rc;
205 
206 	(void) state; /* unused */
207 
208 	rc = getnameinfo(NULL,
209 			 0,
210 			 host, sizeof(host),
211 			 serv, sizeof(serv),
212 			 flags);
213 	assert_int_equal(rc, EAI_FAMILY);
214 
215 	/* IPv4 */
216 	sin.sin_family = AF_INET;
217 	sin.sin_port = htons(22);
218 	rc = inet_pton(AF_INET, "127.0.0.11", &sin.sin_addr);
219 	assert_int_equal(rc, 1);
220 
221 	rc = getnameinfo((const struct sockaddr *)&sin,
222 			 sizeof(struct sockaddr_in),
223 			 NULL, 0,
224 			 serv, sizeof(serv),
225 			 flags);
226 	assert_int_equal(rc, 0);
227 
228 	assert_string_equal(serv, "ssh");
229 
230 	/* IPv6 */
231 	sin6.sin6_family = AF_INET6;
232 	sin6.sin6_port = htons(22);
233 	rc = inet_pton(AF_INET6, "::13", &sin6.sin6_addr);
234 	assert_int_equal(rc, 1);
235 
236 	rc = getnameinfo((const struct sockaddr *)&sin6,
237 			 sizeof(struct sockaddr_in6),
238 			 host, sizeof(host),
239 			 NULL, 0,
240 			 flags);
241 	assert_int_equal(rc, 0);
242 
243 	assert_string_equal(host, "beteigeuze.galaxy.site");
244 
245 	/* IPv6 */
246 	sin6.sin6_family = AF_INET6;
247 	sin6.sin6_port = htons(22);
248 	rc = inet_pton(AF_INET6, "::13", &sin6.sin6_addr);
249 	assert_int_equal(rc, 1);
250 
251 	rc = getnameinfo((const struct sockaddr *)&sin6,
252 			 sizeof(struct sockaddr_in6),
253 			 NULL, 0,
254 			 NULL, 0,
255 			 flags);
256 	assert_int_equal(rc, 0);
257 
258 	assert_string_equal(host, "beteigeuze.galaxy.site");
259 }
260 
test_nwrap_getnameinfo_flags(void ** state)261 static void test_nwrap_getnameinfo_flags(void **state)
262 {
263 	char host[256] = {0};
264 	char serv[256] = {0};
265 	struct sockaddr_in sin;
266 	int flags = 0;
267 	int rc;
268 
269 	(void) state; /* unused */
270 
271 	/* NI_NAMEREQD */
272 	sin.sin_family = AF_INET;
273 	sin.sin_port = htons(22);
274 	rc = inet_pton(AF_INET, "127.0.0.11", &sin.sin_addr);
275 	assert_int_equal(rc, 1);
276 
277 	flags = NI_NAMEREQD;
278 
279 	rc = getnameinfo((const struct sockaddr *)&sin,
280 			 sizeof(struct sockaddr_in),
281 			 NULL, 0,
282 			 NULL, 0,
283 			 flags);
284 	assert_int_equal(rc, EAI_NONAME);
285 
286 	/* NI_DGRAM */
287 	sin.sin_family = AF_INET;
288 	sin.sin_port = htons(513);
289 	rc = inet_pton(AF_INET, "127.0.0.11", &sin.sin_addr);
290 	assert_int_equal(rc, 1);
291 
292 	flags = NI_DGRAM;
293 
294 	rc = getnameinfo((const struct sockaddr *)&sin,
295 			 sizeof(struct sockaddr_in),
296 			 host, sizeof(host),
297 			 serv, sizeof(serv),
298 			 flags);
299 	assert_int_equal(rc, 0);
300 
301 	assert_string_equal(serv, "who");
302 
303 	/* STREAM (port 513) */
304 	flags = 0;
305 
306 	rc = getnameinfo((const struct sockaddr *)&sin,
307 			 sizeof(struct sockaddr_in),
308 			 host, sizeof(host),
309 			 serv, sizeof(serv),
310 			 flags);
311 	assert_int_equal(rc, 0);
312 
313 	assert_string_equal(serv, "login");
314 
315 	/* NI_NOFQDN */
316 	flags = NI_NOFQDN;
317 
318 	rc = getnameinfo((const struct sockaddr *)&sin,
319 			 sizeof(struct sockaddr_in),
320 			 host, sizeof(host),
321 			 serv, sizeof(serv),
322 			 flags);
323 	assert_int_equal(rc, 0);
324 
325 	assert_string_equal(host, "magrathea");
326 }
327 
main(void)328 int main(void) {
329 	int rc;
330 
331 	const struct CMUnitTest tests[] = {
332 		cmocka_unit_test(test_nwrap_getnameinfo),
333 		cmocka_unit_test(test_nwrap_getnameinfo_numeric),
334 		cmocka_unit_test(test_nwrap_getnameinfo_any),
335 		cmocka_unit_test(test_nwrap_getnameinfo_local),
336 		cmocka_unit_test(test_nwrap_getnameinfo_null),
337 		cmocka_unit_test(test_nwrap_getnameinfo_flags),
338 	};
339 
340 	rc = cmocka_run_group_tests(tests, NULL, NULL);
341 
342 	return rc;
343 }
344