1 /*
2 * Copyright (c) 2019 Laird Connectivity
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_REGISTER(net_test, CONFIG_DNS_RESOLVER_LOG_LEVEL);
9
10 #include <zephyr/types.h>
11 #include <stdbool.h>
12 #include <stddef.h>
13 #include <string.h>
14 #include <errno.h>
15 #include <zephyr/sys/printk.h>
16 #include <zephyr/random/random.h>
17
18 #include <zephyr/ztest.h>
19
20 #include <zephyr/net/ethernet.h>
21 #include <zephyr/net/dummy.h>
22 #include <zephyr/net_buf.h>
23 #include <zephyr/net/net_ip.h>
24 #include <zephyr/net/net_if.h>
25 #include <zephyr/net/dns_resolve.h>
26 #include <zephyr/net/net_event.h>
27 #include <zephyr/net/net_mgmt.h>
28
29 #define NET_LOG_ENABLED 1
30 #include "net_private.h"
31
32 #if defined(CONFIG_DNS_RESOLVER_LOG_LEVEL_DBG)
33 #define DBG(fmt, ...) printk(fmt, ##__VA_ARGS__)
34 #else
35 #define DBG(fmt, ...)
36 #endif
37
38 #define NAME4 "4.zephyr.test"
39 #define NAME6 "6.zephyr.test"
40 #define NAME_IPV4 "192.0.2.1"
41 #define NAME_IPV6 "2001:db8::1"
42
43 #define DNS_NAME_IPV4 "192.0.2.4"
44 #define DNS2_NAME_IPV4 "192.0.2.5"
45 #define DNS_NAME_IPV6 "2001:db8::4"
46
47 #define DNS_TIMEOUT 500 /* ms */
48
49 #if defined(CONFIG_NET_IPV6)
50 /* Interface 1 addresses */
51 static struct in6_addr my_addr1 = { { { 0x20, 0x01, 0x0d, 0xb8, 1, 0, 0, 0,
52 0, 0, 0, 0, 0, 0, 0, 0x1 } } };
53 #endif
54
55 #if defined(CONFIG_NET_IPV4)
56 /* Interface 1 addresses */
57 static struct in_addr my_addr2 = { { { 192, 0, 2, 1 } } };
58 #endif
59
60 static struct net_mgmt_event_callback mgmt_cb;
61 static struct k_sem dns_added;
62 static struct k_sem dns_removed;
63
64 static struct net_if *iface1;
65
66 #if defined(CONFIG_NET_IPV4)
67 static struct dns_resolve_context resv_ipv4;
68 static struct dns_resolve_context resv_ipv4_2;
69 #endif
70 #if defined(CONFIG_NET_IPV6)
71 static struct dns_resolve_context resv_ipv6;
72 static struct dns_resolve_context resv_ipv6_2;
73 #endif
74
75 /* this must be higher that the DNS_TIMEOUT */
76 #define WAIT_TIME K_MSEC((DNS_TIMEOUT + 300) * 3)
77
78 struct net_if_test {
79 uint8_t idx;
80 uint8_t mac_addr[sizeof(struct net_eth_addr)];
81 };
82
net_iface_get_mac(const struct device * dev)83 static uint8_t *net_iface_get_mac(const struct device *dev)
84 {
85 struct net_if_test *data = dev->data;
86
87 if (data->mac_addr[2] == 0x00) {
88 /* 00-00-5E-00-53-xx Documentation RFC 7042 */
89 data->mac_addr[0] = 0x00;
90 data->mac_addr[1] = 0x00;
91 data->mac_addr[2] = 0x5E;
92 data->mac_addr[3] = 0x00;
93 data->mac_addr[4] = 0x53;
94 data->mac_addr[5] = sys_rand8_get();
95 }
96
97 return data->mac_addr;
98 }
99
net_iface_init(struct net_if * iface)100 static void net_iface_init(struct net_if *iface)
101 {
102 uint8_t *mac = net_iface_get_mac(net_if_get_device(iface));
103
104 net_if_set_link_addr(iface, mac, sizeof(struct net_eth_addr),
105 NET_LINK_ETHERNET);
106 }
107
sender_iface(const struct device * dev,struct net_pkt * pkt)108 static int sender_iface(const struct device *dev, struct net_pkt *pkt)
109 {
110 if (!pkt->frags) {
111 DBG("No data to send!\n");
112 return -ENODATA;
113 }
114
115 return 0;
116 }
117
118 struct net_if_test net_iface1_data;
119
120 static struct dummy_api net_iface_api = {
121 .iface_api.init = net_iface_init,
122 .send = sender_iface,
123 };
124
125 #define _ETH_L2_LAYER DUMMY_L2
126 #define _ETH_L2_CTX_TYPE NET_L2_GET_CTX_TYPE(DUMMY_L2)
127
128 NET_DEVICE_INIT_INSTANCE(net_iface1_test,
129 "iface1",
130 iface1,
131 NULL,
132 NULL,
133 &net_iface1_data,
134 NULL,
135 CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
136 &net_iface_api,
137 _ETH_L2_LAYER,
138 _ETH_L2_CTX_TYPE,
139 127);
140
dns_evt_handler(struct net_mgmt_event_callback * cb,uint32_t mgmt_event,struct net_if * iface)141 static void dns_evt_handler(struct net_mgmt_event_callback *cb,
142 uint32_t mgmt_event, struct net_if *iface)
143 {
144 if (mgmt_event == NET_EVENT_DNS_SERVER_ADD) {
145 k_sem_give(&dns_added);
146 } else if (mgmt_event == NET_EVENT_DNS_SERVER_DEL) {
147 k_sem_give(&dns_removed);
148 }
149 }
150
test_init(void)151 static void *test_init(void)
152 {
153 struct net_if_addr *ifaddr;
154
155 #if defined(CONFIG_NET_IPV4)
156 dns_resolve_init(&resv_ipv4, NULL, NULL);
157 dns_resolve_init(&resv_ipv4_2, NULL, NULL);
158 #endif
159 #if defined(CONFIG_NET_IPV6)
160 dns_resolve_init(&resv_ipv6, NULL, NULL);
161 dns_resolve_init(&resv_ipv6_2, NULL, NULL);
162 #endif
163
164 iface1 = net_if_get_by_index(0);
165 zassert_is_null(iface1, "iface1");
166
167 iface1 = net_if_get_by_index(1);
168
169 ((struct net_if_test *) net_if_get_device(iface1)->data)->idx =
170 net_if_get_by_iface(iface1);
171
172 #if defined(CONFIG_NET_IPV6)
173 ifaddr = net_if_ipv6_addr_add(iface1, &my_addr1,
174 NET_ADDR_MANUAL, 0);
175 if (!ifaddr) {
176 DBG("Cannot add IPv6 address %s\n",
177 net_sprint_ipv6_addr(&my_addr1));
178 zassert_not_null(ifaddr, "addr1");
179
180 return NULL;
181 }
182
183 /* For testing purposes we need to set the adddresses preferred */
184 ifaddr->addr_state = NET_ADDR_PREFERRED;
185 #endif
186
187 #if defined(CONFIG_NET_IPV4)
188 ifaddr = net_if_ipv4_addr_add(iface1, &my_addr2,
189 NET_ADDR_MANUAL, 0);
190 if (!ifaddr) {
191 DBG("Cannot add IPv4 address %s\n",
192 net_sprint_ipv4_addr(&my_addr2));
193 zassert_not_null(ifaddr, "addr2");
194
195 return NULL;
196 }
197
198 ifaddr->addr_state = NET_ADDR_PREFERRED;
199 #endif
200
201 net_if_up(iface1);
202
203 k_sem_init(&dns_added, 0, 1);
204 k_sem_init(&dns_removed, 0, 1);
205
206 net_mgmt_init_event_callback(&mgmt_cb, dns_evt_handler,
207 NET_EVENT_DNS_SERVER_ADD |
208 NET_EVENT_DNS_SERVER_DEL);
209 net_mgmt_add_event_callback(&mgmt_cb);
210
211 return NULL;
212 }
213
test_dns_do_not_add_add_callback6(void)214 static void test_dns_do_not_add_add_callback6(void)
215 {
216 #if defined(CONFIG_NET_IPV6)
217 /* Wait for DNS added callback without adding DNS */
218
219 k_yield(); /* mandatory so that net_if send func gets to run */
220
221 if (k_sem_take(&dns_added, WAIT_TIME)) {
222 zassert_true(true,
223 "Received DNS added callback when should not have");
224 }
225 #endif
226 }
227
228 /* Wait for DNS added callback after adding DNS */
test_dns_add_callback6(void)229 static void test_dns_add_callback6(void)
230 {
231 #if defined(CONFIG_NET_IPV6)
232
233 struct dns_resolve_context *dnsCtx = &resv_ipv6;
234 const char *dns_servers_str[] = { DNS_NAME_IPV6, NULL };
235 int ret;
236
237 dns_resolve_close(dnsCtx);
238
239 ret = dns_resolve_init(dnsCtx, dns_servers_str, NULL);
240 if (ret < 0) {
241 LOG_ERR("dns_resolve_init fail (%d)", ret);
242 return;
243 }
244
245 k_yield(); /* mandatory so that net_if send func gets to run */
246
247 if (k_sem_take(&dns_added, WAIT_TIME)) {
248 zassert_true(false,
249 "Timeout while waiting for DNS added callback");
250 }
251 #endif
252 }
253
test_dns_remove_callback6(void)254 static void test_dns_remove_callback6(void)
255 {
256 #if defined(CONFIG_NET_IPV6)
257 /* Wait for DNS removed callback after removing DNS */
258
259 int ret;
260
261 ret = dns_resolve_close(&resv_ipv6);
262
263 zassert_equal(ret, 0, "Cannot remove DNS server");
264
265 k_yield(); /* mandatory so that net_if send func gets to run */
266
267 if (k_sem_take(&dns_removed, WAIT_TIME)) {
268 zassert_true(false,
269 "Timeout while waiting for DNS removed callback");
270 }
271 #endif
272 }
273
test_dns_remove_none_callback6(void)274 static void test_dns_remove_none_callback6(void)
275 {
276 #if defined(CONFIG_NET_IPV6)
277 /* Wait for DNS removed callback without removing DNS */
278 int ret;
279
280 ret = dns_resolve_close(&resv_ipv6);
281
282 zassert_not_equal(ret, 0, "Cannot remove DNS server");
283
284 k_yield(); /* mandatory so that net_if send func gets to run */
285
286 if (k_sem_take(&dns_removed, WAIT_TIME)) {
287 zassert_true(true,
288 "Received DNS removed callback when should not have");
289 }
290 #endif
291 }
292
ZTEST(dns_addremove,test_dns_add_remove_two_callback6)293 ZTEST(dns_addremove, test_dns_add_remove_two_callback6)
294 {
295 #if defined(CONFIG_NET_IPV6)
296 struct dns_resolve_context *dnsCtx = &resv_ipv6;
297 const char *dns_servers_str[] = { DNS_NAME_IPV6, NULL };
298 int ret;
299
300 dns_resolve_close(dnsCtx);
301
302 ret = dns_resolve_init(dnsCtx, dns_servers_str, NULL);
303 if (ret < 0) {
304 LOG_ERR("dns_resolve_init fail (%d)", ret);
305 return;
306 }
307
308 k_yield(); /* mandatory so that net_if send func gets to run */
309
310 if (k_sem_take(&dns_added, WAIT_TIME)) {
311 zassert_true(false,
312 "Timeout while waiting for DNS added callback");
313 }
314
315 /* Add second DNS entry */
316 dnsCtx = &resv_ipv6_2;
317 dns_resolve_close(dnsCtx);
318
319 ret = dns_resolve_init(dnsCtx, dns_servers_str, NULL);
320 if (ret < 0) {
321 LOG_ERR("dns_resolve_init fail (%d)", ret);
322 return;
323 }
324
325 k_yield(); /* mandatory so that net_if send func gets to run */
326
327 if (k_sem_take(&dns_added, WAIT_TIME)) {
328 zassert_true(false,
329 "Timeout while waiting for DNS added callback");
330 }
331
332 /* Check both DNS servers are active */
333 zassert_equal(resv_ipv6.state, DNS_RESOLVE_CONTEXT_ACTIVE,
334 "DNS server #1 is missing");
335 zassert_equal(resv_ipv6_2.state, DNS_RESOLVE_CONTEXT_ACTIVE,
336 "DNS server #2 is missing");
337
338 /* Remove first DNS server */
339 dnsCtx = &resv_ipv6;
340 ret = dns_resolve_close(dnsCtx);
341 zassert_equal(ret, 0, "Cannot remove DNS server #1");
342
343 k_yield(); /* mandatory so that net_if send func gets to run */
344
345 if (k_sem_take(&dns_removed, WAIT_TIME)) {
346 zassert_true(true,
347 "Received DNS removed callback when should not have");
348 }
349
350 /* Check second DNS server is active */
351 zassert_equal(resv_ipv6.state, DNS_RESOLVE_CONTEXT_INACTIVE,
352 "DNS server #1 is active");
353 zassert_equal(resv_ipv6_2.state, DNS_RESOLVE_CONTEXT_ACTIVE,
354 "DNS server #2 is missing");
355
356 /* Check first DNS server cannot be removed once removed */
357 ret = dns_resolve_close(dnsCtx);
358 zassert_not_equal(ret, 0,
359 "Successful result code when attempting to "
360 "remove DNS server #1 again");
361
362 /* Remove second DNS server */
363 dnsCtx = &resv_ipv6_2;
364 ret = dns_resolve_close(dnsCtx);
365 zassert_equal(ret, 0, "Cannot remove DNS server #2");
366
367 k_yield(); /* mandatory so that net_if send func gets to run */
368
369 if (k_sem_take(&dns_removed, WAIT_TIME)) {
370 zassert_true(true,
371 "Received DNS removed callback when should "
372 "not have");
373 }
374
375 /* Check neither DNS server is used */
376 zassert_equal(resv_ipv6.state, DNS_RESOLVE_CONTEXT_INACTIVE,
377 "DNS server #1 is active");
378 zassert_equal(resv_ipv6_2.state, DNS_RESOLVE_CONTEXT_INACTIVE,
379 "DNS server #2 is active");
380
381 /* Check first DNS server cannot be removed once removed */
382 ret = dns_resolve_close(dnsCtx);
383 zassert_not_equal(ret, 0,
384 "Successful result code when attempting "
385 "to remove DNS server #1 again");
386 #endif
387 }
388
test_dns_do_not_add_add_callback(void)389 static void test_dns_do_not_add_add_callback(void)
390 {
391 #if defined(CONFIG_NET_IPV4)
392 /* Wait for DNS added callback without adding DNS */
393
394 k_yield(); /* mandatory so that net_if send func gets to run */
395
396 if (k_sem_take(&dns_added, WAIT_TIME)) {
397 zassert_true(true,
398 "Received DNS added callback when should not have");
399 }
400 #endif
401 }
402
test_dns_add_callback(void)403 static void test_dns_add_callback(void)
404 {
405 #if defined(CONFIG_NET_IPV4)
406 /* Wait for DNS added callback after adding DNS */
407 struct dns_resolve_context *dnsCtx = &resv_ipv4;
408 const char *dns_servers_str[] = { DNS_NAME_IPV4, NULL };
409 int ret;
410
411 dns_resolve_close(dnsCtx);
412
413 ret = dns_resolve_init(dnsCtx, dns_servers_str, NULL);
414 if (ret < 0) {
415 LOG_ERR("dns_resolve_init fail (%d)", ret);
416 return;
417 }
418
419 k_yield(); /* mandatory so that net_if send func gets to run */
420
421 if (k_sem_take(&dns_added, WAIT_TIME)) {
422 zassert_true(false,
423 "Timeout while waiting for DNS added callback");
424 }
425 #endif
426 }
427
test_dns_remove_callback(void)428 static void test_dns_remove_callback(void)
429 {
430 #if defined(CONFIG_NET_IPV4)
431 /* Wait for DNS removed callback after removing DNS */
432 int ret;
433
434 ret = dns_resolve_close(&resv_ipv4);
435
436 zassert_equal(ret, 0, "Cannot remove DNS server");
437
438 k_yield(); /* mandatory so that net_if send func gets to run */
439
440 if (k_sem_take(&dns_removed, WAIT_TIME)) {
441 zassert_true(false,
442 "Timeout while waiting for DNS removed callback");
443 }
444 #endif
445 }
446
ZTEST(dns_addremove,test_dns_reconfigure_callback)447 ZTEST(dns_addremove, test_dns_reconfigure_callback)
448 {
449 #if defined(CONFIG_NET_IPV4)
450 struct dns_resolve_context *dnsCtx = &resv_ipv4;
451 const char *dns_servers_str[] = { DNS_NAME_IPV4, NULL };
452 const char *dns2_servers_str[] = { DNS2_NAME_IPV4, NULL };
453 int ret;
454
455 ret = dns_resolve_init(dnsCtx, dns_servers_str, NULL);
456 if (ret < 0) {
457 LOG_ERR("dns_resolve_init fail (%d)", ret);
458 return;
459 }
460
461 k_yield(); /* mandatory so that net_if send func gets to run */
462
463 /* Wait for DNS added callback after adding DNS */
464 if (k_sem_take(&dns_added, WAIT_TIME)) {
465 zassert_true(false,
466 "Timeout while waiting for DNS added callback");
467 }
468
469 ret = dns_resolve_reconfigure(&resv_ipv4, dns2_servers_str, NULL);
470 zassert_equal(ret, 0, "Cannot reconfigure DNS server");
471
472 /* Wait for DNS removed callback after reconfiguring DNS */
473 if (k_sem_take(&dns_removed, WAIT_TIME)) {
474 zassert_true(false,
475 "Timeout while waiting for DNS removed callback");
476 }
477
478 /* Wait for DNS added callback after reconfiguring DNS */
479 if (k_sem_take(&dns_added, WAIT_TIME)) {
480 zassert_true(false,
481 "Timeout while waiting for DNS added callback");
482 }
483
484 ret = dns_resolve_close(&resv_ipv4);
485 zassert_equal(ret, 0, "Cannot remove DNS server");
486
487 k_yield(); /* mandatory so that net_if send func gets to run */
488
489 /* Wait for DNS removed callback after removing DNS */
490 if (k_sem_take(&dns_removed, WAIT_TIME)) {
491 zassert_true(false,
492 "Timeout while waiting for DNS removed callback");
493 }
494 #endif
495 }
496
test_dns_remove_none_callback(void)497 static void test_dns_remove_none_callback(void)
498 {
499 #if defined(CONFIG_NET_IPV4)
500 /* Wait for DNS removed callback without removing DNS */
501 int ret;
502
503 ret = dns_resolve_close(&resv_ipv4);
504
505 zassert_not_equal(ret, 0, "Cannot remove DNS server");
506
507 k_yield(); /* mandatory so that net_if send func gets to run */
508
509 if (k_sem_take(&dns_removed, WAIT_TIME)) {
510 zassert_true(true,
511 "Received DNS removed callback when should not have");
512 }
513 #endif
514 }
515
ZTEST(dns_addremove,test_dns_add_remove_two_callback)516 ZTEST(dns_addremove, test_dns_add_remove_two_callback)
517 {
518 #if defined(CONFIG_NET_IPV4)
519 struct dns_resolve_context *dnsCtx = &resv_ipv4;
520 const char *dns_servers_str[] = { DNS_NAME_IPV4, NULL };
521 int ret;
522
523 dns_resolve_close(dnsCtx);
524
525 ret = dns_resolve_init(dnsCtx, dns_servers_str, NULL);
526 if (ret < 0) {
527 LOG_ERR("dns_resolve_init fail (%d)", ret);
528 return;
529 }
530
531 k_yield(); /* mandatory so that net_if send func gets to run */
532
533 if (k_sem_take(&dns_added, WAIT_TIME)) {
534 zassert_true(false,
535 "Timeout while waiting for DNS added callback");
536 }
537
538 /* Add second DNS entry */
539 dnsCtx = &resv_ipv4_2;
540 dns_resolve_close(dnsCtx);
541
542 ret = dns_resolve_init(dnsCtx, dns_servers_str, NULL);
543 if (ret < 0) {
544 LOG_ERR("dns_resolve_init fail (%d)", ret);
545 return;
546 }
547
548 k_yield(); /* mandatory so that net_if send func gets to run */
549
550 if (k_sem_take(&dns_added, WAIT_TIME)) {
551 zassert_true(false,
552 "Timeout while waiting for DNS added callback");
553 }
554
555 /* Check both DNS servers are used */
556 zassert_equal(resv_ipv4.state, DNS_RESOLVE_CONTEXT_ACTIVE,
557 "DNS server #1 is missing");
558 zassert_equal(resv_ipv4_2.state, DNS_RESOLVE_CONTEXT_ACTIVE,
559 "DNS server #2 is missing");
560
561 /* Remove first DNS server */
562 dnsCtx = &resv_ipv4;
563 ret = dns_resolve_close(dnsCtx);
564 zassert_equal(ret, 0, "Cannot remove DNS server #1");
565
566 k_yield(); /* mandatory so that net_if send func gets to run */
567
568 if (k_sem_take(&dns_removed, WAIT_TIME)) {
569 zassert_true(true,
570 "Received DNS removed callback when should not have");
571 }
572
573 /* Check second DNS servers is used */
574 zassert_equal(resv_ipv4.state, DNS_RESOLVE_CONTEXT_INACTIVE,
575 "DNS server #1 is active");
576 zassert_equal(resv_ipv4_2.state, DNS_RESOLVE_CONTEXT_ACTIVE,
577 "DNS server #2 is missing");
578
579 /* Check first DNS server cannot be removed once removed */
580 ret = dns_resolve_close(dnsCtx);
581 zassert_not_equal(ret, 0,
582 "Successful result code when attempting to "
583 "remove DNS server #1 again");
584
585 /* Remove second DNS server */
586 dnsCtx = &resv_ipv4_2;
587 ret = dns_resolve_close(dnsCtx);
588 zassert_equal(ret, 0, "Cannot remove DNS server #2");
589
590 k_yield(); /* mandatory so that net_if send func gets to run */
591
592 if (k_sem_take(&dns_removed, WAIT_TIME)) {
593 zassert_true(true,
594 "Received DNS removed callback when should "
595 "not have");
596 }
597
598 /* Check neither DNS server is used */
599 zassert_equal(resv_ipv4.state, DNS_RESOLVE_CONTEXT_INACTIVE,
600 "DNS server #1 is active");
601 zassert_equal(resv_ipv4_2.state, DNS_RESOLVE_CONTEXT_INACTIVE,
602 "DNS server #2 is active");
603
604 /* Check first DNS server cannot be removed once removed */
605 ret = dns_resolve_close(dnsCtx);
606 zassert_not_equal(ret, 0,
607 "Successful result code when attempting to "
608 "remove DNS server #1 again");
609 #endif
610 }
611
ZTEST(dns_addremove,test_dns_addremove_v6)612 ZTEST(dns_addremove, test_dns_addremove_v6)
613 {
614 test_dns_do_not_add_add_callback6();
615 test_dns_add_callback6();
616 test_dns_remove_callback6();
617 test_dns_remove_none_callback6();
618 }
619
ZTEST(dns_addremove,test_dns_addremove_v4)620 ZTEST(dns_addremove, test_dns_addremove_v4)
621 {
622 test_dns_do_not_add_add_callback();
623 test_dns_add_callback();
624 test_dns_remove_callback();
625 test_dns_remove_none_callback();
626 }
627
628 ZTEST_SUITE(dns_addremove, NULL, test_init, NULL, NULL, NULL);
629