1 /*
2 * Copyright (c) 2018-2020 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <logging/log.h>
8 LOG_MODULE_REGISTER(net_test, CONFIG_NET_SOCKETS_LOG_LEVEL);
9
10 #include <stdio.h>
11 #include <ztest_assert.h>
12 #include <sys/sem.h>
13 #include <net/socket.h>
14 #include <net/dns_resolve.h>
15 #include <net/buf.h>
16
17 #include "../../socket_helpers.h"
18
19 #include "dns_pack.h"
20
21 #define QUERY_HOST "www.zephyrproject.org"
22
23 #define ANY_PORT 0
24 #define MAX_BUF_SIZE 128
25 #define STACK_SIZE (1024 + CONFIG_TEST_EXTRA_STACKSIZE)
26 #define THREAD_PRIORITY K_PRIO_COOP(2)
27 #define WAIT_TIME K_MSEC(250)
28
29 static uint8_t recv_buf[MAX_BUF_SIZE];
30
31 static int sock_v4;
32 static int sock_v6;
33
34 static struct sockaddr_in addr_v4;
35 static struct sockaddr_in6 addr_v6;
36
37 static int queries_received;
38
39 /* The semaphore is there to wait the data to be received. */
40 static ZTEST_BMEM struct sys_sem wait_data;
41
42 NET_BUF_POOL_DEFINE(test_dns_msg_pool, 1, 512, 0, NULL);
43
check_dns_query(uint8_t * buf,int buf_len)44 static bool check_dns_query(uint8_t *buf, int buf_len)
45 {
46 struct dns_msg_t dns_msg;
47 struct net_buf *result;
48 enum dns_rr_type qtype;
49 enum dns_class qclass;
50 int ret, queries;
51
52 /* Store the DNS query name into a temporary net_buf as that is
53 * expected by dns_unpack_query() function. In this test we are
54 * currently not sending any DNS response back as that is not
55 * really needed by these tests.
56 */
57 result = net_buf_alloc(&test_dns_msg_pool, K_FOREVER);
58 if (!result) {
59 ret = -ENOMEM;
60 return false;
61 }
62
63 dns_msg.msg = buf;
64 dns_msg.msg_size = buf_len;
65
66 ret = mdns_unpack_query_header(&dns_msg, NULL);
67 if (ret < 0) {
68 return false;
69 }
70
71 queries = ret;
72 queries_received++;
73
74 NET_DBG("Received %d %s", queries,
75 queries > 1 ? "queries" : "query");
76
77 (void)memset(result->data, 0, net_buf_tailroom(result));
78 result->len = 0U;
79
80 ret = dns_unpack_query(&dns_msg, result, &qtype, &qclass);
81 if (ret < 0) {
82 net_buf_unref(result);
83 return false;
84 }
85
86 NET_DBG("[%d] query %s/%s label %s (%d bytes)", queries,
87 qtype == DNS_RR_TYPE_A ? "A" : "AAAA", "IN",
88 log_strdup(result->data), ret);
89
90 /* In this test we are just checking if the query came to us in correct
91 * form, we are not creating a DNS server implementation here.
92 */
93 if (strncmp(result->data + 1, QUERY_HOST,
94 sizeof(QUERY_HOST) - 1)) {
95 net_buf_unref(result);
96 return false;
97 }
98
99 net_buf_unref(result);
100
101 return true;
102 }
103
process_dns(void)104 static int process_dns(void)
105 {
106 struct pollfd pollfds[2];
107 struct sockaddr *addr;
108 socklen_t addr_len;
109 int ret, idx;
110
111 NET_DBG("Waiting for IPv4 DNS packets on port %d",
112 ntohs(addr_v4.sin_port));
113 NET_DBG("Waiting for IPv6 DNS packets on port %d",
114 ntohs(addr_v6.sin6_port));
115
116 while (true) {
117 memset(pollfds, 0, sizeof(pollfds));
118 pollfds[0].fd = sock_v4;
119 pollfds[0].events = POLLIN;
120 pollfds[1].fd = sock_v6;
121 pollfds[1].events = POLLIN;
122
123 NET_DBG("Polling...");
124
125 ret = poll(pollfds, ARRAY_SIZE(pollfds), -1);
126 if (ret <= 0) {
127 continue;
128 }
129
130 for (idx = 0; idx < ARRAY_SIZE(pollfds); idx++) {
131 if (pollfds[idx].revents & POLLIN) {
132 if (pollfds[idx].fd == sock_v4) {
133 addr_len = sizeof(addr_v4);
134 addr = (struct sockaddr *)&addr_v4;
135 } else {
136 addr_len = sizeof(addr_v6);
137 addr = (struct sockaddr *)&addr_v6;
138 }
139
140 ret = recvfrom(pollfds[idx].fd,
141 recv_buf, sizeof(recv_buf), 0,
142 addr, &addr_len);
143 if (ret < 0) {
144 /* Socket error */
145 NET_ERR("DNS: Connection error (%d)",
146 errno);
147 break;
148 }
149
150 NET_DBG("Received DNS query");
151
152 ret = check_dns_query(recv_buf,
153 sizeof(recv_buf));
154 if (ret) {
155 (void)sys_sem_give(&wait_data);
156 }
157 }
158 }
159 }
160
161 return -errno;
162 }
163
164 K_THREAD_DEFINE(dns_server_thread_id, STACK_SIZE,
165 process_dns, NULL, NULL, NULL,
166 THREAD_PRIORITY, 0, -1);
167
test_getaddrinfo_setup(void)168 void test_getaddrinfo_setup(void)
169 {
170 char str[INET6_ADDRSTRLEN], *addr_str;
171 struct sockaddr addr;
172 int ret;
173
174 ret = net_ipaddr_parse(CONFIG_DNS_SERVER1,
175 sizeof(CONFIG_DNS_SERVER1) - 1,
176 &addr);
177 zassert_true(ret, "Cannot parse IP address %s", CONFIG_DNS_SERVER1);
178
179 if (addr.sa_family == AF_INET) {
180 memcpy(&addr_v4, net_sin(&addr), sizeof(struct sockaddr_in));
181 } else if (addr.sa_family == AF_INET6) {
182 memcpy(&addr_v6, net_sin6(&addr), sizeof(struct sockaddr_in6));
183 }
184
185 ret = net_ipaddr_parse(CONFIG_DNS_SERVER2,
186 sizeof(CONFIG_DNS_SERVER2) - 1,
187 &addr);
188 zassert_true(ret, "Cannot parse IP address %s", CONFIG_DNS_SERVER2);
189
190 if (addr.sa_family == AF_INET) {
191 memcpy(&addr_v4, net_sin(&addr), sizeof(struct sockaddr_in));
192 } else if (addr.sa_family == AF_INET6) {
193 memcpy(&addr_v6, net_sin6(&addr), sizeof(struct sockaddr_in6));
194 }
195
196 addr_str = inet_ntop(AF_INET, &addr_v4.sin_addr, str, sizeof(str));
197 NET_DBG("v4: [%s]:%d", log_strdup(addr_str), ntohs(addr_v4.sin_port));
198
199 sock_v4 = prepare_listen_sock_udp_v4(&addr_v4);
200 zassert_true(sock_v4 >= 0, "Invalid IPv4 socket");
201
202 addr_str = inet_ntop(AF_INET6, &addr_v6.sin6_addr, str, sizeof(str));
203 NET_DBG("v6: [%s]:%d", log_strdup(addr_str), ntohs(addr_v6.sin6_port));
204
205 sock_v6 = prepare_listen_sock_udp_v6(&addr_v6);
206 zassert_true(sock_v6 >= 0, "Invalid IPv6 socket");
207
208 sys_sem_init(&wait_data, 0, INT_MAX);
209
210 k_thread_start(dns_server_thread_id);
211
212 k_thread_priority_set(dns_server_thread_id,
213 k_thread_priority_get(k_current_get()));
214 k_yield();
215 }
216
test_getaddrinfo_ok(void)217 void test_getaddrinfo_ok(void)
218 {
219 struct addrinfo *res = NULL;
220
221 queries_received = 0;
222
223 /* This check simulates a local query that we will catch
224 * in process_dns() function. So we do not check the res variable
225 * as that will currently not contain anything useful. We just check
226 * that the query triggered a function call to process_dns() function
227 * and that it could parse the DNS query.
228 */
229 (void)getaddrinfo(QUERY_HOST, NULL, NULL, &res);
230
231 if (sys_sem_count_get(&wait_data) != 2) {
232 zassert_true(false, "Did not receive all queries");
233 }
234
235 (void)sys_sem_take(&wait_data, K_NO_WAIT);
236 (void)sys_sem_take(&wait_data, K_NO_WAIT);
237
238 zassert_equal(queries_received, 2,
239 "Did not receive both IPv4 and IPv6 query");
240
241 freeaddrinfo(res);
242 }
243
test_getaddrinfo_cancelled(void)244 void test_getaddrinfo_cancelled(void)
245 {
246 struct addrinfo *res = NULL;
247 int ret;
248
249 ret = getaddrinfo(QUERY_HOST, NULL, NULL, &res);
250
251 if (sys_sem_count_get(&wait_data) != 2) {
252 zassert_true(false, "Did not receive all queries");
253 }
254
255 (void)sys_sem_take(&wait_data, K_NO_WAIT);
256 (void)sys_sem_take(&wait_data, K_NO_WAIT);
257
258 /* Without a local DNS server this request will be canceled. */
259 zassert_equal(ret, DNS_EAI_CANCELED, "Invalid result");
260
261 freeaddrinfo(res);
262 }
263
test_getaddrinfo_no_host(void)264 void test_getaddrinfo_no_host(void)
265 {
266 struct addrinfo *res = NULL;
267 int ret;
268
269 ret = getaddrinfo(NULL, NULL, NULL, &res);
270
271 zassert_equal(ret, DNS_EAI_SYSTEM, "Invalid result");
272 zassert_equal(errno, EINVAL, "Invalid errno");
273 zassert_is_null(res, "ai_addr is not NULL");
274
275 freeaddrinfo(res);
276 }
277
test_getaddrinfo_num_ipv4(void)278 void test_getaddrinfo_num_ipv4(void)
279 {
280 struct zsock_addrinfo *res = NULL;
281 struct sockaddr_in *saddr;
282 int ret;
283
284 struct zsock_addrinfo hints = {
285 .ai_family = AF_INET,
286 .ai_socktype = SOCK_STREAM
287 };
288
289 ret = zsock_getaddrinfo("1.2.3.255", "65534", NULL, &res);
290
291 zassert_equal(ret, 0, "Invalid result");
292 zassert_not_null(res, "");
293 zassert_is_null(res->ai_next, "");
294 zassert_equal(res->ai_family, AF_INET, "");
295 zassert_equal(res->ai_socktype, SOCK_STREAM, "");
296 zassert_equal(res->ai_protocol, IPPROTO_TCP, "");
297 zsock_freeaddrinfo(res);
298
299 ret = zsock_getaddrinfo("1.2.3.255", "65534", &hints, &res);
300 zassert_equal(ret, 0, "Invalid result");
301 zassert_not_null(res, "");
302 zassert_is_null(res->ai_next, "");
303 zassert_equal(res->ai_family, AF_INET, "");
304 zassert_equal(res->ai_socktype, SOCK_STREAM, "");
305 zassert_equal(res->ai_protocol, IPPROTO_TCP, "");
306 zsock_freeaddrinfo(res);
307
308 hints.ai_socktype = SOCK_DGRAM;
309 ret = zsock_getaddrinfo("1.2.3.255", "65534", &hints, &res);
310 zassert_equal(ret, 0, "Invalid result");
311 zassert_not_null(res, "");
312 zassert_is_null(res->ai_next, "");
313 zassert_equal(res->ai_family, AF_INET, "");
314 zassert_equal(res->ai_socktype, SOCK_DGRAM, "");
315 zassert_equal(res->ai_protocol, IPPROTO_UDP, "");
316
317 saddr = (struct sockaddr_in *)res->ai_addr;
318 zassert_equal(saddr->sin_family, AF_INET, "");
319 zassert_equal(saddr->sin_port, htons(65534), "");
320 zassert_equal(saddr->sin_addr.s4_addr[0], 1, "");
321 zassert_equal(saddr->sin_addr.s4_addr[1], 2, "");
322 zassert_equal(saddr->sin_addr.s4_addr[2], 3, "");
323 zassert_equal(saddr->sin_addr.s4_addr[3], 255, "");
324 zsock_freeaddrinfo(res);
325 }
326
test_getaddrinfo_num_ipv6(void)327 void test_getaddrinfo_num_ipv6(void)
328 {
329 struct zsock_addrinfo *res = NULL;
330 struct sockaddr_in6 *saddr;
331 int ret;
332
333 struct zsock_addrinfo hints = {
334 .ai_family = AF_INET6,
335 .ai_socktype = SOCK_STREAM
336 };
337
338 ret = zsock_getaddrinfo("[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]",
339 "65534", NULL, &res);
340
341 zassert_equal(ret, 0, "Invalid result");
342 zassert_not_null(res, "");
343 zassert_is_null(res->ai_next, "");
344 zassert_equal(res->ai_family, AF_INET6, "");
345 zassert_equal(res->ai_socktype, SOCK_STREAM, "");
346 zassert_equal(res->ai_protocol, IPPROTO_TCP, "");
347
348 saddr = (struct sockaddr_in6 *)res->ai_addr;
349 zassert_equal(saddr->sin6_family, AF_INET6, "");
350 zassert_equal(saddr->sin6_port, htons(65534), "");
351 zassert_equal(saddr->sin6_addr.s6_addr[0], 0xFE, "");
352 zassert_equal(saddr->sin6_addr.s6_addr[1], 0xDC, "");
353 zassert_equal(saddr->sin6_addr.s6_addr[2], 0xBA, "");
354 zassert_equal(saddr->sin6_addr.s6_addr[3], 0x98, "");
355 zassert_equal(saddr->sin6_addr.s6_addr[4], 0x76, "");
356 zassert_equal(saddr->sin6_addr.s6_addr[5], 0x54, "");
357 zassert_equal(saddr->sin6_addr.s6_addr[6], 0x32, "");
358 zassert_equal(saddr->sin6_addr.s6_addr[7], 0x10, "");
359 zassert_equal(saddr->sin6_addr.s6_addr[8], 0xFE, "");
360 zassert_equal(saddr->sin6_addr.s6_addr[9], 0xDC, "");
361 zassert_equal(saddr->sin6_addr.s6_addr[10], 0xBA, "");
362 zassert_equal(saddr->sin6_addr.s6_addr[11], 0x98, "");
363 zassert_equal(saddr->sin6_addr.s6_addr[12], 0x76, "");
364 zassert_equal(saddr->sin6_addr.s6_addr[13], 0x54, "");
365 zassert_equal(saddr->sin6_addr.s6_addr[14], 0x32, "");
366 zassert_equal(saddr->sin6_addr.s6_addr[15], 0x10, "");
367 zsock_freeaddrinfo(res);
368
369
370 ret = zsock_getaddrinfo("[1080:0:0:0:8:800:200C:417A]",
371 "65534", &hints, &res);
372 zassert_equal(ret, 0, "Invalid result");
373 zassert_not_null(res, "");
374 zassert_is_null(res->ai_next, "");
375 zassert_equal(res->ai_family, AF_INET6, "");
376 zassert_equal(res->ai_socktype, SOCK_STREAM, "");
377 zassert_equal(res->ai_protocol, IPPROTO_TCP, "");
378
379 saddr = (struct sockaddr_in6 *)res->ai_addr;
380 zassert_equal(saddr->sin6_family, AF_INET6, "");
381 zassert_equal(saddr->sin6_port, htons(65534), "");
382 zassert_equal(saddr->sin6_addr.s6_addr[0], 0x10, "");
383 zassert_equal(saddr->sin6_addr.s6_addr[1], 0x80, "");
384 zassert_equal(saddr->sin6_addr.s6_addr[2], 0x0, "");
385 zassert_equal(saddr->sin6_addr.s6_addr[3], 0x0, "");
386 zassert_equal(saddr->sin6_addr.s6_addr[4], 0x0, "");
387 zassert_equal(saddr->sin6_addr.s6_addr[5], 0x0, "");
388 zassert_equal(saddr->sin6_addr.s6_addr[6], 0x0, "");
389 zassert_equal(saddr->sin6_addr.s6_addr[7], 0x0, "");
390 zassert_equal(saddr->sin6_addr.s6_addr[8], 0x0, "");
391 zassert_equal(saddr->sin6_addr.s6_addr[9], 0x08, "");
392 zassert_equal(saddr->sin6_addr.s6_addr[10], 0x08, "");
393 zassert_equal(saddr->sin6_addr.s6_addr[11], 0x00, "");
394 zassert_equal(saddr->sin6_addr.s6_addr[12], 0x20, "");
395 zassert_equal(saddr->sin6_addr.s6_addr[13], 0x0C, "");
396 zassert_equal(saddr->sin6_addr.s6_addr[14], 0x41, "");
397 zassert_equal(saddr->sin6_addr.s6_addr[15], 0x7A, "");
398 zsock_freeaddrinfo(res);
399
400
401 hints.ai_socktype = SOCK_DGRAM;
402 ret = zsock_getaddrinfo("[3ffe:2a00:100:7031::1]",
403 "65534", &hints, &res);
404 zassert_equal(ret, 0, "Invalid result");
405 zassert_not_null(res, "");
406 zassert_is_null(res->ai_next, "");
407 zassert_equal(res->ai_family, AF_INET6, "");
408 zassert_equal(res->ai_socktype, SOCK_DGRAM, "");
409 zassert_equal(res->ai_protocol, IPPROTO_UDP, "");
410
411 saddr = (struct sockaddr_in6 *)res->ai_addr;
412 zassert_equal(saddr->sin6_family, AF_INET6, "");
413 zassert_equal(saddr->sin6_port, htons(65534), "");
414 zassert_equal(saddr->sin6_addr.s6_addr[0], 0x3f, "");
415 zassert_equal(saddr->sin6_addr.s6_addr[1], 0xfe, "");
416 zassert_equal(saddr->sin6_addr.s6_addr[2], 0x2a, "");
417 zassert_equal(saddr->sin6_addr.s6_addr[3], 0x00, "");
418 zassert_equal(saddr->sin6_addr.s6_addr[4], 0x01, "");
419 zassert_equal(saddr->sin6_addr.s6_addr[5], 0x00, "");
420 zassert_equal(saddr->sin6_addr.s6_addr[6], 0x70, "");
421 zassert_equal(saddr->sin6_addr.s6_addr[7], 0x31, "");
422 zassert_equal(saddr->sin6_addr.s6_addr[8], 0x0, "");
423 zassert_equal(saddr->sin6_addr.s6_addr[9], 0x0, "");
424 zassert_equal(saddr->sin6_addr.s6_addr[10], 0x0, "");
425 zassert_equal(saddr->sin6_addr.s6_addr[11], 0x0, "");
426 zassert_equal(saddr->sin6_addr.s6_addr[12], 0x0, "");
427 zassert_equal(saddr->sin6_addr.s6_addr[13], 0x0, "");
428 zassert_equal(saddr->sin6_addr.s6_addr[14], 0x0, "");
429 zassert_equal(saddr->sin6_addr.s6_addr[15], 0x1, "");
430 zsock_freeaddrinfo(res);
431
432
433 ret = zsock_getaddrinfo("[1080::8:800:200C:417A]",
434 "65534", &hints, &res);
435 zassert_equal(ret, 0, "Invalid result");
436
437 saddr = (struct sockaddr_in6 *)res->ai_addr;
438 zassert_equal(saddr->sin6_family, AF_INET6, "");
439 zassert_equal(saddr->sin6_port, htons(65534), "");
440 zassert_equal(saddr->sin6_addr.s6_addr[0], 0x10, "");
441 zassert_equal(saddr->sin6_addr.s6_addr[1], 0x80, "");
442 zassert_equal(saddr->sin6_addr.s6_addr[2], 0x0, "");
443 zassert_equal(saddr->sin6_addr.s6_addr[3], 0x0, "");
444 zassert_equal(saddr->sin6_addr.s6_addr[4], 0x0, "");
445 zassert_equal(saddr->sin6_addr.s6_addr[5], 0x0, "");
446 zassert_equal(saddr->sin6_addr.s6_addr[6], 0x0, "");
447 zassert_equal(saddr->sin6_addr.s6_addr[7], 0x0, "");
448 zassert_equal(saddr->sin6_addr.s6_addr[8], 0x0, "");
449 zassert_equal(saddr->sin6_addr.s6_addr[9], 0x8, "");
450 zassert_equal(saddr->sin6_addr.s6_addr[10], 0x08, "");
451 zassert_equal(saddr->sin6_addr.s6_addr[11], 0x00, "");
452 zassert_equal(saddr->sin6_addr.s6_addr[12], 0x20, "");
453 zassert_equal(saddr->sin6_addr.s6_addr[13], 0x0C, "");
454 zassert_equal(saddr->sin6_addr.s6_addr[14], 0x41, "");
455 zassert_equal(saddr->sin6_addr.s6_addr[15], 0x7A, "");
456 zsock_freeaddrinfo(res);
457
458
459 ret = zsock_getaddrinfo("[::192.9.5.5]", "65534", &hints, &res);
460 zassert_equal(ret, 0, "Invalid result");
461
462 saddr = (struct sockaddr_in6 *)res->ai_addr;
463 zassert_equal(saddr->sin6_family, AF_INET6, "");
464 zassert_equal(saddr->sin6_port, htons(65534), "");
465 zassert_equal(saddr->sin6_addr.s6_addr[0], 0x0, "");
466 zassert_equal(saddr->sin6_addr.s6_addr[1], 0x0, "");
467 zassert_equal(saddr->sin6_addr.s6_addr[2], 0x0, "");
468 zassert_equal(saddr->sin6_addr.s6_addr[3], 0x0, "");
469 zassert_equal(saddr->sin6_addr.s6_addr[4], 0x0, "");
470 zassert_equal(saddr->sin6_addr.s6_addr[5], 0x0, "");
471 zassert_equal(saddr->sin6_addr.s6_addr[6], 0x0, "");
472 zassert_equal(saddr->sin6_addr.s6_addr[7], 0x0, "");
473 zassert_equal(saddr->sin6_addr.s6_addr[8], 0x0, "");
474 zassert_equal(saddr->sin6_addr.s6_addr[9], 0x0, "");
475 zassert_equal(saddr->sin6_addr.s6_addr[10], 0x0, "");
476 zassert_equal(saddr->sin6_addr.s6_addr[11], 0x0, "");
477 zassert_equal(saddr->sin6_addr.s6_addr[12], 192, "");
478 zassert_equal(saddr->sin6_addr.s6_addr[13], 9, "");
479 zassert_equal(saddr->sin6_addr.s6_addr[14], 5, "");
480 zassert_equal(saddr->sin6_addr.s6_addr[15], 5, "");
481 zsock_freeaddrinfo(res);
482
483
484 ret = zsock_getaddrinfo("[::FFFF:129.144.52.38]",
485 "65534", &hints, &res);
486 zassert_equal(ret, 0, "Invalid result");
487
488 saddr = (struct sockaddr_in6 *)res->ai_addr;
489 zassert_equal(saddr->sin6_family, AF_INET6, "");
490 zassert_equal(saddr->sin6_port, htons(65534), "");
491 zassert_equal(saddr->sin6_addr.s6_addr[0], 0x0, "");
492 zassert_equal(saddr->sin6_addr.s6_addr[1], 0x0, "");
493 zassert_equal(saddr->sin6_addr.s6_addr[2], 0x0, "");
494 zassert_equal(saddr->sin6_addr.s6_addr[3], 0x0, "");
495 zassert_equal(saddr->sin6_addr.s6_addr[4], 0x0, "");
496 zassert_equal(saddr->sin6_addr.s6_addr[5], 0x0, "");
497 zassert_equal(saddr->sin6_addr.s6_addr[6], 0x0, "");
498 zassert_equal(saddr->sin6_addr.s6_addr[7], 0x0, "");
499 zassert_equal(saddr->sin6_addr.s6_addr[8], 0x0, "");
500 zassert_equal(saddr->sin6_addr.s6_addr[9], 0x0, "");
501 zassert_equal(saddr->sin6_addr.s6_addr[10], 0xFF, "");
502 zassert_equal(saddr->sin6_addr.s6_addr[11], 0xFF, "");
503 zassert_equal(saddr->sin6_addr.s6_addr[12], 129, "");
504 zassert_equal(saddr->sin6_addr.s6_addr[13], 144, "");
505 zassert_equal(saddr->sin6_addr.s6_addr[14], 52, "");
506 zassert_equal(saddr->sin6_addr.s6_addr[15], 38, "");
507 zsock_freeaddrinfo(res);
508
509
510 ret = zsock_getaddrinfo("[2010:836B:4179::836B:4179]",
511 "65534", &hints, &res);
512 zassert_equal(ret, 0, "Invalid result");
513
514 saddr = (struct sockaddr_in6 *)res->ai_addr;
515 zassert_equal(saddr->sin6_family, AF_INET6, "");
516 zassert_equal(saddr->sin6_port, htons(65534), "");
517 zassert_equal(saddr->sin6_addr.s6_addr[0], 0x20, "");
518 zassert_equal(saddr->sin6_addr.s6_addr[1], 0x10, "");
519 zassert_equal(saddr->sin6_addr.s6_addr[2], 0x83, "");
520 zassert_equal(saddr->sin6_addr.s6_addr[3], 0x6B, "");
521 zassert_equal(saddr->sin6_addr.s6_addr[4], 0x41, "");
522 zassert_equal(saddr->sin6_addr.s6_addr[5], 0x79, "");
523 zassert_equal(saddr->sin6_addr.s6_addr[6], 0x0, "");
524 zassert_equal(saddr->sin6_addr.s6_addr[7], 0x0, "");
525 zassert_equal(saddr->sin6_addr.s6_addr[8], 0x0, "");
526 zassert_equal(saddr->sin6_addr.s6_addr[9], 0x0, "");
527 zassert_equal(saddr->sin6_addr.s6_addr[10], 0x0, "");
528 zassert_equal(saddr->sin6_addr.s6_addr[11], 0x0, "");
529 zassert_equal(saddr->sin6_addr.s6_addr[12], 0x83, "");
530 zassert_equal(saddr->sin6_addr.s6_addr[13], 0x6B, "");
531 zassert_equal(saddr->sin6_addr.s6_addr[14], 0x41, "");
532 zassert_equal(saddr->sin6_addr.s6_addr[15], 0x79, "");
533 zsock_freeaddrinfo(res);
534 }
535
test_getaddrinfo_flags_numerichost(void)536 void test_getaddrinfo_flags_numerichost(void)
537 {
538 int ret;
539 struct zsock_addrinfo *res = NULL;
540 struct zsock_addrinfo hints = {
541 .ai_flags = AI_NUMERICHOST,
542 };
543
544 ret = zsock_getaddrinfo("foo.bar", "65534", &hints, &res);
545 zassert_equal(ret, DNS_EAI_FAIL, "Invalid result");
546 zassert_is_null(res, "");
547
548 ret = zsock_getaddrinfo("1.2.3.4", "65534", &hints, &res);
549 zassert_equal(ret, 0, "Invalid result");
550 zassert_not_null(res, "");
551
552 zsock_freeaddrinfo(res);
553 }
554
test_getaddrinfo_ipv4_hints_ipv6(void)555 static void test_getaddrinfo_ipv4_hints_ipv6(void)
556 {
557 struct zsock_addrinfo *res = NULL;
558 struct zsock_addrinfo hints = {
559 .ai_family = AF_INET6,
560 };
561 int ret;
562
563 ret = zsock_getaddrinfo("192.0.2.1", NULL, &hints, &res);
564 zassert_equal(ret, DNS_EAI_ADDRFAMILY, "Invalid result (%d)", ret);
565 zassert_is_null(res, "");
566 zsock_freeaddrinfo(res);
567 }
568
test_getaddrinfo_ipv6_hints_ipv4(void)569 static void test_getaddrinfo_ipv6_hints_ipv4(void)
570 {
571 struct zsock_addrinfo *res = NULL;
572 struct zsock_addrinfo hints = {
573 .ai_family = AF_INET,
574 };
575 int ret;
576
577 ret = zsock_getaddrinfo("2001:db8::1", NULL, &hints, &res);
578 zassert_equal(ret, DNS_EAI_ADDRFAMILY, "Invalid result (%d)", ret);
579 zassert_is_null(res, "");
580 zsock_freeaddrinfo(res);
581 }
582
test_getaddrinfo_port_invalid(void)583 static void test_getaddrinfo_port_invalid(void)
584 {
585 int ret;
586 struct zsock_addrinfo *res = NULL;
587 ret = zsock_getaddrinfo("192.0.2.1", "70000", NULL, &res);
588 zassert_equal(ret, DNS_EAI_NONAME, "Invalid result (%d)", ret);
589 zassert_is_null(res, "");
590 zsock_freeaddrinfo(res);
591 }
592
test_getaddrinfo_null_host(void)593 static void test_getaddrinfo_null_host(void)
594 {
595 struct sockaddr_in *saddr;
596 struct sockaddr_in6 *saddr6;
597 struct zsock_addrinfo *res = NULL;
598 struct zsock_addrinfo hints = {
599 .ai_family = AF_INET,
600 .ai_socktype = SOCK_STREAM,
601 .ai_flags = AI_PASSIVE
602 };
603 int ret;
604
605 /* Test IPv4 TCP */
606 ret = zsock_getaddrinfo(NULL, "80", &hints, &res);
607 zassert_equal(ret, 0, "Invalid result");
608 zassert_not_null(res, "");
609 zassert_is_null(res->ai_next, "");
610 zassert_equal(res->ai_family, AF_INET, "");
611 zassert_equal(res->ai_socktype, SOCK_STREAM, "");
612 zassert_equal(res->ai_protocol, IPPROTO_TCP, "");
613 saddr = net_sin(res->ai_addr);
614 zassert_equal(saddr->sin_family, AF_INET, "");
615 zassert_equal(saddr->sin_port, htons(80), "");
616 zassert_equal(saddr->sin_addr.s_addr, INADDR_ANY, "");
617 zsock_freeaddrinfo(res);
618
619 /* Test IPv6 TCP */
620 hints.ai_family = AF_INET6;
621 ret = zsock_getaddrinfo(NULL, "80", &hints, &res);
622 zassert_equal(ret, 0, "Invalid result");
623 zassert_not_null(res, "");
624 zassert_is_null(res->ai_next, "");
625 zassert_equal(res->ai_family, AF_INET6, "");
626 zassert_equal(res->ai_socktype, SOCK_STREAM, "");
627 zassert_equal(res->ai_protocol, IPPROTO_TCP, "");
628 saddr6 = net_sin6(res->ai_addr);
629 zassert_equal(saddr6->sin6_family, AF_INET6, "");
630 zassert_equal(saddr6->sin6_port, htons(80), "");
631 zassert_equal(0, memcmp(&saddr6->sin6_addr, &in6addr_any, sizeof(in6addr_any)), "");
632 zsock_freeaddrinfo(res);
633
634 /* Test IPv6 UDP */
635 hints.ai_socktype = SOCK_DGRAM;
636 ret = zsock_getaddrinfo(NULL, "80", &hints, &res);
637 zassert_equal(ret, 0, "Invalid result");
638 zassert_not_null(res, "");
639 zassert_is_null(res->ai_next, "");
640 zassert_equal(res->ai_family, AF_INET6, "");
641 zassert_equal(res->ai_socktype, SOCK_DGRAM, "");
642 zassert_equal(res->ai_protocol, IPPROTO_UDP, "");
643 saddr6 = (struct sockaddr_in6 *)res->ai_addr;
644 zassert_equal(saddr6->sin6_family, AF_INET6, "");
645 zassert_equal(saddr6->sin6_port, htons(80), "");
646 zsock_freeaddrinfo(res);
647
648 /* Test IPv4 UDP */
649 hints.ai_family = AF_INET;
650 ret = zsock_getaddrinfo(NULL, "80", &hints, &res);
651 zassert_equal(ret, 0, "Invalid result");
652 zassert_not_null(res, "");
653 zassert_is_null(res->ai_next, "");
654 zassert_equal(res->ai_family, AF_INET, "");
655 zassert_equal(res->ai_socktype, SOCK_DGRAM, "");
656 zassert_equal(res->ai_protocol, IPPROTO_UDP, "");
657 saddr = (struct sockaddr_in *)res->ai_addr;
658 zassert_equal(saddr->sin_family, AF_INET, "");
659 zassert_equal(saddr->sin_port, htons(80), "");
660 zsock_freeaddrinfo(res);
661 }
662
663
test_main(void)664 void test_main(void)
665 {
666 k_thread_system_pool_assign(k_current_get());
667 k_thread_access_grant(k_current_get(), &wait_data);
668
669 ztest_test_suite(socket_getaddrinfo,
670 ztest_unit_test(test_getaddrinfo_setup),
671 ztest_unit_test(test_getaddrinfo_ok),
672 ztest_unit_test(test_getaddrinfo_cancelled),
673 ztest_unit_test(test_getaddrinfo_no_host),
674 ztest_unit_test(test_getaddrinfo_num_ipv4),
675 ztest_unit_test(test_getaddrinfo_num_ipv6),
676 ztest_unit_test(test_getaddrinfo_flags_numerichost),
677 ztest_unit_test(test_getaddrinfo_ipv4_hints_ipv6),
678 ztest_unit_test(test_getaddrinfo_ipv6_hints_ipv4),
679 ztest_unit_test(test_getaddrinfo_port_invalid),
680 ztest_unit_test(test_getaddrinfo_null_host));
681
682 ztest_run_test_suite(socket_getaddrinfo);
683 }
684