1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
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 #include <zephyr/net/socket_service.h>
29 
30 #define NET_LOG_ENABLED 1
31 #include "net_private.h"
32 
33 #if defined(CONFIG_DNS_RESOLVER_LOG_LEVEL_DBG)
34 #define DBG(fmt, ...) printk(fmt, ##__VA_ARGS__)
35 #else
36 #define DBG(fmt, ...)
37 #endif
38 
39 #define NAME4 "4.zephyr.test"
40 #define NAME6 "6.zephyr.test"
41 #define NAME_IPV4 "192.0.2.1"
42 #define NAME_IPV6 "2001:db8::1"
43 
44 #define DNS_NAME_IPV4 "192.0.2.4"
45 #define DNS2_NAME_IPV4 "192.0.2.5"
46 #define DNS_NAME_IPV6 "2001:db8::4"
47 
48 #define DNS_TIMEOUT 500 /* ms */
49 
50 #if defined(CONFIG_NET_IPV6)
51 /* Interface 1 addresses */
52 static struct in6_addr my_addr1 = { { { 0x20, 0x01, 0x0d, 0xb8, 1, 0, 0, 0,
53 					0, 0, 0, 0, 0, 0, 0, 0x1 } } };
54 #endif
55 
56 #if defined(CONFIG_NET_IPV4)
57 /* Interface 1 addresses */
58 static struct in_addr my_addr2 = { { { 192, 0, 2, 1 } } };
59 #endif
60 
61 static struct net_if *iface1;
62 
63 /* this must be higher that the DNS_TIMEOUT */
64 #define WAIT_TIME K_MSEC((DNS_TIMEOUT + 300) * 3)
65 
66 struct net_if_test {
67 	uint8_t idx;
68 	uint8_t mac_addr[sizeof(struct net_eth_addr)];
69 };
70 
net_iface_get_mac(const struct device * dev)71 static uint8_t *net_iface_get_mac(const struct device *dev)
72 {
73 	struct net_if_test *data = dev->data;
74 
75 	if (data->mac_addr[2] == 0x00) {
76 		/* 00-00-5E-00-53-xx Documentation RFC 7042 */
77 		data->mac_addr[0] = 0x00;
78 		data->mac_addr[1] = 0x00;
79 		data->mac_addr[2] = 0x5E;
80 		data->mac_addr[3] = 0x00;
81 		data->mac_addr[4] = 0x53;
82 		data->mac_addr[5] = sys_rand8_get();
83 	}
84 
85 	return data->mac_addr;
86 }
87 
net_iface_init(struct net_if * iface)88 static void net_iface_init(struct net_if *iface)
89 {
90 	uint8_t *mac = net_iface_get_mac(net_if_get_device(iface));
91 
92 	net_if_set_link_addr(iface, mac, sizeof(struct net_eth_addr),
93 			     NET_LINK_ETHERNET);
94 }
95 
sender_iface(const struct device * dev,struct net_pkt * pkt)96 static int sender_iface(const struct device *dev, struct net_pkt *pkt)
97 {
98 	if (!pkt->frags) {
99 		DBG("No data to send!\n");
100 		return -ENODATA;
101 	}
102 
103 	return 0;
104 }
105 
106 struct net_if_test net_iface1_data;
107 
108 static struct dummy_api net_iface_api = {
109 	.iface_api.init = net_iface_init,
110 	.send = sender_iface,
111 };
112 
113 #define _ETH_L2_LAYER DUMMY_L2
114 #define _ETH_L2_CTX_TYPE NET_L2_GET_CTX_TYPE(DUMMY_L2)
115 
116 NET_DEVICE_INIT_INSTANCE(net_iface1_test,
117 			 "iface1",
118 			 iface1,
119 			 NULL,
120 			 NULL,
121 			 &net_iface1_data,
122 			 NULL,
123 			 CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
124 			 &net_iface_api,
125 			 _ETH_L2_LAYER,
126 			 _ETH_L2_CTX_TYPE,
127 			 127);
128 
test_init(void)129 static void *test_init(void)
130 {
131 	struct net_if_addr *ifaddr;
132 
133 	iface1 = net_if_get_by_index(0);
134 	zassert_is_null(iface1, "iface1");
135 
136 	iface1 = net_if_get_by_index(1);
137 
138 	((struct net_if_test *) net_if_get_device(iface1)->data)->idx =
139 		net_if_get_by_iface(iface1);
140 
141 #if defined(CONFIG_NET_IPV6)
142 	ifaddr = net_if_ipv6_addr_add(iface1, &my_addr1,
143 				      NET_ADDR_MANUAL, 0);
144 	if (!ifaddr) {
145 		DBG("Cannot add IPv6 address %s\n",
146 		       net_sprint_ipv6_addr(&my_addr1));
147 		zassert_not_null(ifaddr, "addr1");
148 
149 		return NULL;
150 	}
151 
152 	/* For testing purposes we need to set the adddresses preferred */
153 	ifaddr->addr_state = NET_ADDR_PREFERRED;
154 #endif
155 
156 #if defined(CONFIG_NET_IPV4)
157 	ifaddr = net_if_ipv4_addr_add(iface1, &my_addr2,
158 				      NET_ADDR_MANUAL, 0);
159 	if (!ifaddr) {
160 		DBG("Cannot add IPv4 address %s\n",
161 		       net_sprint_ipv4_addr(&my_addr2));
162 		zassert_not_null(ifaddr, "addr2");
163 
164 		return NULL;
165 	}
166 
167 	ifaddr->addr_state = NET_ADDR_PREFERRED;
168 #endif
169 
170 	net_if_up(iface1);
171 
172 	return NULL;
173 }
174 
ZTEST(dns_dispatcher,test_dns_dispatcher)175 ZTEST(dns_dispatcher, test_dns_dispatcher)
176 {
177 	struct dns_resolve_context *ctx;
178 	int sock1, sock2 = -1;
179 
180 	ctx = dns_resolve_get_default();
181 
182 	dns_resolve_init_default(ctx);
183 
184 	sock1 = ctx->servers[0].sock;
185 
186 	for (int i = 0; i < ctx->servers[0].dispatcher.fds_len; i++) {
187 		if (ctx->servers[0].dispatcher.fds[i].fd == sock1) {
188 			sock2 = i;
189 			break;
190 		}
191 	}
192 
193 	zassert_not_equal(sock2, -1, "Cannot find socket");
194 
195 	k_sleep(K_MSEC(10));
196 
197 	dns_resolve_close(ctx);
198 
199 	zassert_equal(ctx->servers[0].dispatcher.fds[sock2].fd, -1, "Socket not closed");
200 	zassert_equal(ctx->servers[0].dispatcher.sock, -1, "Dispatcher still registered");
201 }
202 
203 ZTEST_SUITE(dns_dispatcher, NULL, test_init, NULL, NULL, NULL);
204