1 /*
2  * Copyright 2025 NXP
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "openthread/platform/mdns_socket.h"
8 #include <openthread/nat64.h>
9 #include <openthread/platform/messagepool.h>
10 #include "openthread/instance.h"
11 #include "openthread_border_router.h"
12 #include "platform-zephyr.h"
13 #include <common/code_utils.hpp>
14 #include <zephyr/net/mld.h>
15 #include <zephyr/net/net_context.h>
16 #include <zephyr/net/socket.h>
17 #include <zephyr/net/net_if.h>
18 #include <zephyr/net/net_ip.h>
19 #include <zephyr/net/net_pkt.h>
20 #include <zephyr/net/openthread.h>
21 #include <zephyr/net/socket_service.h>
22 #include "sockets_internal.h"
23 #include <errno.h>
24 
25 #define MULTICAST_PORT 5353
26 #define MAX_SERVICES CONFIG_OPENTHREAD_ZEPHYR_BORDER_ROUTER_MAX_MDNS_SERVICES
27 #define PKT_THRESHOLD_VAL CONFIG_OPENTHREAD_ZEPHYR_BORDER_ROUTER_MDNS_BUFFER_THRESHOLD
28 
29 static struct zsock_pollfd sockfd_udp[MAX_SERVICES];
30 static int mdns_sock_v6 = -1;
31 #if defined(CONFIG_NET_IPV4)
32 static int mdns_sock_v4 = -1;
33 #endif /* CONFIG_NET_IPV4 */
34 static struct otInstance *ot_instance_ptr;
35 static uint32_t ail_iface_index;
36 static bool mdns_socket_is_enabled;
37 
38 static otError mdns_socket_init_v6(uint32_t ail_iface_idx);
39 #if defined(CONFIG_NET_IPV4)
40 static otError mdns_socket_init_v4(uint32_t ail_iface_idx);
41 #endif /* CONFIG_NET_IPV4 */
42 static otError mdns_socket_deinit(void);
43 static otError set_listening_enable(otInstance *instance, bool enable, uint32_t ail_iface_idx);
44 static void mdns_send_multicast(otMessage *message, uint32_t ail_iface_idx);
45 static void mdns_send_unicast(otMessage *message, const otPlatMdnsAddressInfo *aAddress);
46 static void mdns_receive_handler(struct net_socket_service_event *evt);
47 static void process_mdns_message(struct otbr_msg_ctx *msg_ctx_ptr);
48 
49 NET_SOCKET_SERVICE_SYNC_DEFINE_STATIC(mdns_udp_service, mdns_receive_handler, MAX_SERVICES);
50 
mdns_plat_socket_init(otInstance * ot_instance,uint32_t ail_iface_idx)51 otError mdns_plat_socket_init(otInstance *ot_instance, uint32_t ail_iface_idx)
52 {
53 	ot_instance_ptr = ot_instance;
54 	ail_iface_index = ail_iface_idx;
55 
56 	return OT_ERROR_NONE;
57 }
58 
otPlatMdnsSetListeningEnabled(otInstance * aInstance,bool aEnable,uint32_t aInfraIfIndex)59 otError otPlatMdnsSetListeningEnabled(otInstance *aInstance, bool aEnable, uint32_t aInfraIfIndex)
60 {
61 	return set_listening_enable(aInstance, aEnable, aInfraIfIndex);
62 }
63 
otPlatMdnsSendMulticast(otInstance * aInstance,otMessage * aMessage,uint32_t aInfraIfIndex)64 void otPlatMdnsSendMulticast(otInstance *aInstance, otMessage *aMessage, uint32_t aInfraIfIndex)
65 {
66 	OT_UNUSED_VARIABLE(aInstance);
67 
68 	mdns_send_multicast(aMessage, aInfraIfIndex);
69 }
70 
otPlatMdnsSendUnicast(otInstance * aInstance,otMessage * aMessage,const otPlatMdnsAddressInfo * aAddress)71 void otPlatMdnsSendUnicast(otInstance *aInstance, otMessage *aMessage,
72 			   const otPlatMdnsAddressInfo *aAddress)
73 {
74 	OT_UNUSED_VARIABLE(aInstance);
75 
76 	mdns_send_unicast(aMessage, aAddress);
77 }
78 
set_listening_enable(otInstance * instance,bool enable,uint32_t ail_iface_idx)79 static otError set_listening_enable(otInstance *instance, bool enable, uint32_t ail_iface_idx)
80 {
81 	OT_UNUSED_VARIABLE(instance);
82 	otError error = OT_ERROR_NONE;
83 
84 	if (enable) {
85 		SuccessOrExit(error = mdns_socket_init_v6(ail_iface_idx));
86 #if defined(CONFIG_NET_IPV4)
87 		SuccessOrExit(error = mdns_socket_init_v4(ail_iface_idx));
88 #endif /* CONFIG_NET_IPV4 */
89 		mdns_socket_is_enabled = true;
90 		mdns_plat_monitor_interface(net_if_get_by_index(ail_iface_idx));
91 		ExitNow();
92 	}
93 
94 	SuccessOrExit(error = mdns_socket_deinit());
95 	mdns_socket_is_enabled = false;
96 exit:
97 	return error;
98 
99 }
100 
mdns_socket_init_v6(uint32_t ail_iface_idx)101 static otError mdns_socket_init_v6(uint32_t ail_iface_idx)
102 {
103 	otError error = OT_ERROR_NONE;
104 	char name[CONFIG_NET_INTERFACE_NAME_LEN + 1] = {0};
105 	struct net_ifreq if_req = {0};
106 	struct net_ipv6_mreq mreq_v6 = {0};
107 	int mcast_hops = 255;
108 	int on = 1;
109 	int mcast_join_ret = 0;
110 
111 	struct net_sockaddr_in6 addr = {.sin6_family = NET_AF_INET6,
112 					.sin6_port = net_htons(MULTICAST_PORT),
113 					.sin6_addr = {{{0}}},
114 					.sin6_scope_id = 0};
115 
116 	mdns_sock_v6 = zsock_socket(NET_AF_INET6, NET_SOCK_DGRAM, NET_IPPROTO_UDP);
117 	VerifyOrExit(mdns_sock_v6 >= 0, error = OT_ERROR_FAILED);
118 	VerifyOrExit(net_if_get_name(net_if_get_by_index(ail_iface_idx), name,
119 				     CONFIG_NET_INTERFACE_NAME_LEN) > 0,
120 		     error = OT_ERROR_FAILED);
121 	memcpy(if_req.ifr_name, name, MIN(sizeof(name) - 1, sizeof(if_req.ifr_name) - 1));
122 	VerifyOrExit(zsock_setsockopt(mdns_sock_v6, ZSOCK_SOL_SOCKET, ZSOCK_SO_BINDTODEVICE,
123 				      &if_req, sizeof(if_req)) == 0,
124 		     error = OT_ERROR_FAILED);
125 	VerifyOrExit(zsock_setsockopt(mdns_sock_v6, ZSOCK_SOL_SOCKET, ZSOCK_SO_REUSEADDR,
126 				      &on, sizeof(on)) == 0,
127 		     error = OT_ERROR_FAILED);
128 	VerifyOrExit(zsock_setsockopt(mdns_sock_v6, ZSOCK_SOL_SOCKET, ZSOCK_SO_REUSEPORT,
129 				      &on, sizeof(on)) == 0,
130 		     error = OT_ERROR_FAILED);
131 	VerifyOrExit(zsock_setsockopt(mdns_sock_v6, NET_IPPROTO_IPV6, ZSOCK_IPV6_V6ONLY, &on,
132 				      sizeof(on)) == 0,
133 		     error = OT_ERROR_FAILED);
134 	mreq_v6.ipv6mr_ifindex = ail_iface_idx;
135 	net_ipv6_addr_create(&mreq_v6.ipv6mr_multiaddr, 0xff02, 0, 0, 0, 0, 0, 0, 0x00fb);
136 	mcast_join_ret = zsock_setsockopt(mdns_sock_v6, NET_IPPROTO_IPV6, ZSOCK_IPV6_ADD_MEMBERSHIP,
137 					  &mreq_v6, sizeof(mreq_v6));
138 	VerifyOrExit(mcast_join_ret == 0 || (mcast_join_ret == -1 && errno == EALREADY),
139 		     error = OT_ERROR_FAILED);
140 	VerifyOrExit(zsock_setsockopt(mdns_sock_v6, NET_IPPROTO_IPV6, ZSOCK_IPV6_MULTICAST_LOOP,
141 				      &on, sizeof(on)) == 0,
142 		     error = OT_ERROR_FAILED);
143 	VerifyOrExit(zsock_setsockopt(mdns_sock_v6, NET_IPPROTO_IPV6, ZSOCK_IPV6_MULTICAST_IF,
144 				      &ail_iface_index, sizeof(ail_iface_index)) == 0,
145 		     error = OT_ERROR_FAILED);
146 	VerifyOrExit(zsock_setsockopt(mdns_sock_v6, NET_IPPROTO_IPV6, ZSOCK_IPV6_MULTICAST_HOPS,
147 				      &mcast_hops, sizeof(mcast_hops)) == 0,
148 		     error = OT_ERROR_FAILED);
149 	VerifyOrExit(zsock_setsockopt(mdns_sock_v6, NET_IPPROTO_IPV6, ZSOCK_IPV6_UNICAST_HOPS,
150 				      &mcast_hops, sizeof(mcast_hops)) == 0,
151 		     error = OT_ERROR_FAILED);
152 	VerifyOrExit(zsock_bind(mdns_sock_v6, (struct net_sockaddr *)&addr, sizeof(addr)) == 0,
153 		     error = OT_ERROR_FAILED);
154 
155 	sockfd_udp[0].fd = mdns_sock_v6;
156 	sockfd_udp[0].events = ZSOCK_POLLIN;
157 
158 	VerifyOrExit(net_socket_service_register(&mdns_udp_service, sockfd_udp,
159 						 ARRAY_SIZE(sockfd_udp), NULL) == 0,
160 		     error = OT_ERROR_FAILED);
161 
162 exit:
163 	return error;
164 }
165 
166 #if defined(CONFIG_NET_IPV4)
mdns_socket_init_v4(uint32_t ail_iface_idx)167 static otError mdns_socket_init_v4(uint32_t ail_iface_idx)
168 {
169 	otError error = OT_ERROR_NONE;
170 	char name[CONFIG_NET_INTERFACE_NAME_LEN + 1] = {0};
171 	struct net_ifreq if_req = {0};
172 	struct net_ip_mreqn mreq_v4 = {0};
173 	int mcast_hops = 255;
174 	int on = 1;
175 	int mcast_join_ret = 0;
176 
177 	struct net_sockaddr_in addr = {.sin_family = NET_AF_INET,
178 				       .sin_port = net_htons(MULTICAST_PORT),
179 				       .sin_addr = {{{0}}}};
180 
181 	mdns_sock_v4 = zsock_socket(NET_AF_INET, NET_SOCK_DGRAM, NET_IPPROTO_UDP);
182 	VerifyOrExit(mdns_sock_v4 >= 0, error = OT_ERROR_FAILED);
183 	VerifyOrExit(net_if_get_name(net_if_get_by_index(ail_iface_idx), name,
184 				     CONFIG_NET_INTERFACE_NAME_LEN) > 0,
185 		     error = OT_ERROR_FAILED);
186 	memcpy(if_req.ifr_name, name, MIN(sizeof(name) - 1, sizeof(if_req.ifr_name) - 1));
187 	VerifyOrExit(zsock_setsockopt(mdns_sock_v4, ZSOCK_SOL_SOCKET, ZSOCK_SO_BINDTODEVICE,
188 				      &if_req, sizeof(if_req)) == 0,
189 		     error = OT_ERROR_FAILED);
190 	VerifyOrExit(zsock_setsockopt(mdns_sock_v4, ZSOCK_SOL_SOCKET, ZSOCK_SO_REUSEADDR,
191 				      &on, sizeof(on)) == 0,
192 		     error = OT_ERROR_FAILED);
193 	VerifyOrExit(zsock_setsockopt(mdns_sock_v4, ZSOCK_SOL_SOCKET, ZSOCK_SO_REUSEPORT,
194 				      &on, sizeof(on)) == 0,
195 		     error = OT_ERROR_FAILED);
196 	mreq_v4.imr_ifindex = ail_iface_idx;
197 	mreq_v4.imr_multiaddr.s_addr = net_htonl(0xE00000FB);
198 	mcast_join_ret = zsock_setsockopt(mdns_sock_v4, NET_IPPROTO_IP, ZSOCK_IP_ADD_MEMBERSHIP,
199 					  &mreq_v4, sizeof(mreq_v4));
200 	VerifyOrExit(mcast_join_ret == 0 || (mcast_join_ret == -1 && errno == EALREADY),
201 		     error = OT_ERROR_FAILED);
202 	VerifyOrExit(zsock_setsockopt(mdns_sock_v4, NET_IPPROTO_IP, ZSOCK_IP_MULTICAST_LOOP,
203 				      &on, sizeof(on)) == 0,
204 		     error = OT_ERROR_FAILED);
205 	VerifyOrExit(zsock_setsockopt(mdns_sock_v4, NET_IPPROTO_IP, ZSOCK_IP_MULTICAST_IF,
206 				      &mreq_v4, sizeof(mreq_v4)) == 0,
207 		     error = OT_ERROR_FAILED);
208 	VerifyOrExit(zsock_setsockopt(mdns_sock_v4, NET_IPPROTO_IP, ZSOCK_IP_MULTICAST_TTL,
209 				      &mcast_hops, sizeof(mcast_hops)) == 0,
210 		     error = OT_ERROR_FAILED);
211 	VerifyOrExit(zsock_setsockopt(mdns_sock_v4, NET_IPPROTO_IP, ZSOCK_IP_TTL,
212 				      &mcast_hops, sizeof(mcast_hops)) == 0,
213 		     error = OT_ERROR_FAILED);
214 	VerifyOrExit(zsock_bind(mdns_sock_v4, (struct net_sockaddr *)&addr, sizeof(addr)) == 0,
215 		     error = OT_ERROR_FAILED);
216 
217 	sockfd_udp[1].fd = mdns_sock_v4;
218 	sockfd_udp[1].events = ZSOCK_POLLIN;
219 
220 	VerifyOrExit(net_socket_service_register(&mdns_udp_service, sockfd_udp,
221 						 ARRAY_SIZE(sockfd_udp), NULL) == 0,
222 		     error = OT_ERROR_FAILED);
223 
224 exit:
225 	return error;
226 }
227 #endif /* CONFIG_NET_IPV4 */
228 
mdns_socket_deinit(void)229 static otError mdns_socket_deinit(void)
230 {
231 	otError error = OT_ERROR_NONE;
232 
233 	VerifyOrExit(mdns_sock_v6 != -1, error = OT_ERROR_INVALID_STATE);
234 	VerifyOrExit(zsock_close(mdns_sock_v6) == 0, error = OT_ERROR_FAILED);
235 
236 	sockfd_udp[0].fd = -1;
237 	mdns_sock_v6 = -1;
238 
239 #if defined(CONFIG_NET_IPV4)
240 	VerifyOrExit(mdns_sock_v4 != -1, error = OT_ERROR_INVALID_STATE);
241 	VerifyOrExit(zsock_close(mdns_sock_v4) == 0, error = OT_ERROR_FAILED);
242 
243 	sockfd_udp[1].fd = -1;
244 	mdns_sock_v4 = -1;
245 #endif /* CONFIG_NET_IPV4 */
246 
247 	VerifyOrExit(net_socket_service_register(&mdns_udp_service, sockfd_udp,
248 						 ARRAY_SIZE(sockfd_udp), NULL) == 0,
249 						 error = OT_ERROR_FAILED);
250 exit:
251 	return error;
252 }
253 
mdns_send_multicast(otMessage * message,uint32_t ail_iface_idx)254 static void mdns_send_multicast(otMessage *message, uint32_t ail_iface_idx)
255 {
256 	uint16_t length = otMessageGetLength(message);
257 	struct otbr_msg_ctx *req = NULL;
258 	struct net_sockaddr_in6 addr_v6 = {.sin6_family = NET_AF_INET6,
259 					   .sin6_port = net_htons(MULTICAST_PORT),
260 					   .sin6_addr = NET_IN6ADDR_ANY_INIT,
261 					   .sin6_scope_id = 0};
262 #if defined(CONFIG_NET_IPV4)
263 	struct net_sockaddr_in addr_v4 = {.sin_family = NET_AF_INET,
264 					  .sin_port = net_htons(MULTICAST_PORT),
265 					  .sin_addr = NET_INADDR_ANY_INIT};
266 #endif /* CONFIG_NET_IPV4*/
267 
268 	VerifyOrExit(length <= OTBR_MESSAGE_SIZE);
269 	VerifyOrExit(openthread_border_router_allocate_message((void **)&req) == OT_ERROR_NONE);
270 
271 	net_ipv6_addr_create(&addr_v6.sin6_addr, 0xff02, 0, 0, 0, 0, 0, 0, 0x00fb);
272 #if defined(CONFIG_NET_IPV4)
273 	addr_v4.sin_addr.s_addr = net_htonl(0xE00000FB);
274 #endif /* CONFIG_NET_IPV4 */
275 
276 	VerifyOrExit(otMessageRead(message, 0, req->buffer, length) == length);
277 
278 	VerifyOrExit(zsock_sendto(mdns_sock_v6, req->buffer, length, 0,
279 				  (struct net_sockaddr *)&addr_v6,
280 				  sizeof(addr_v6)) > 0);
281 #if defined(CONFIG_NET_IPV4)
282 	VerifyOrExit(zsock_sendto(mdns_sock_v4, req->buffer, length, 0,
283 				  (struct net_sockaddr *)&addr_v4,
284 				  sizeof(addr_v4)) > 0);
285 #endif /* CONFIG_NET_IPV4 */
286 exit:
287 	otMessageFree(message);
288 	if (req != NULL) {
289 		openthread_border_router_deallocate_message((void *)req);
290 	}
291 }
292 
mdns_send_unicast(otMessage * message,const otPlatMdnsAddressInfo * aAddress)293 static void mdns_send_unicast(otMessage *message, const otPlatMdnsAddressInfo *aAddress)
294 {
295 	uint16_t length = otMessageGetLength(message);
296 	struct otbr_msg_ctx *req = NULL;
297 	otIp4Address ot_ipv4_addr = {0};
298 #if defined(CONFIG_NET_IPV4)
299 	bool send_ipv4 = false;
300 	struct net_sockaddr_in addr_v4 = {0};
301 #endif /* CONFIG_NET_IPV4*/
302 	struct net_sockaddr_in6 addr_v6 = {.sin6_family = NET_AF_INET6,
303 					   .sin6_port = net_htons(aAddress->mPort),
304 					   .sin6_addr = NET_IN6ADDR_ANY_INIT,
305 					   .sin6_scope_id = 0};
306 
307 	VerifyOrExit(length <= OTBR_MESSAGE_SIZE);
308 	VerifyOrExit(openthread_border_router_allocate_message((void **)&req) == OT_ERROR_NONE);
309 #if defined(CONFIG_NET_IPV4)
310 	if (otIp4FromIp4MappedIp6Address(&aAddress->mAddress, &ot_ipv4_addr) == OT_ERROR_NONE) {
311 		addr_v4.sin_family = NET_AF_INET;
312 		addr_v4.sin_port = net_htons(aAddress->mPort);
313 		memcpy(&addr_v4.sin_addr.s_addr, &ot_ipv4_addr, sizeof(otIp4Address));
314 		send_ipv4 = true;
315 	}
316 #endif /* CONFIG_NET_IPV4 */
317 	memcpy(&addr_v6.sin6_addr, &aAddress->mAddress, sizeof(otIp6Address));
318 
319 	VerifyOrExit(otMessageRead(message, 0, req->buffer, length) == length);
320 
321 	VerifyOrExit(zsock_sendto(mdns_sock_v6, req->buffer, length, 0,
322 				  (struct net_sockaddr *)&addr_v6,
323 				  sizeof(addr_v6)) > 0);
324 #if defined(CONFIG_NET_IPV4)
325 	if (send_ipv4) {
326 		VerifyOrExit(zsock_sendto(mdns_sock_v4, req->buffer, length, 0,
327 					  (struct net_sockaddr *)&addr_v4,
328 					  sizeof(addr_v4)) > 0);
329 	}
330 #endif /* CONFIG_NET_IPV4 */
331 exit:
332 	otMessageFree(message);
333 	if (req != NULL) {
334 		openthread_border_router_deallocate_message((void *)req);
335 	}
336 }
337 
mdns_receive_handler(struct net_socket_service_event * evt)338 static void mdns_receive_handler(struct net_socket_service_event *evt)
339 {
340 	struct net_sockaddr_in6 addr_v6 = {0};
341 #if defined(CONFIG_NET_IPV4)
342 	struct net_sockaddr_in addr_v4 = {0};
343 	net_socklen_t optlen = sizeof(int);
344 #endif /* CONFIG_NET_IPV4 */
345 	net_socklen_t addrlen;
346 	ssize_t len = 0;
347 	int family;
348 	struct otbr_msg_ctx *req = NULL;
349 
350 	VerifyOrExit(evt->event.revents & ZSOCK_POLLIN);
351 	VerifyOrExit(openthread_border_router_allocate_message((void **)&req) == OT_ERROR_NONE);
352 #if defined(CONFIG_NET_IPV4)
353 	(void)zsock_getsockopt(evt->event.fd, ZSOCK_SOL_SOCKET, ZSOCK_SO_DOMAIN, &family, &optlen);
354 
355 	if (family == NET_AF_INET) {
356 		addrlen = sizeof(addr_v4);
357 		len = zsock_recvfrom(mdns_sock_v4, req->buffer, sizeof(req->buffer), 0,
358 				     (struct net_sockaddr *)&addr_v4, &addrlen);
359 		VerifyOrExit(len > 0);
360 		otIp4ToIp4MappedIp6Address((otIp4Address *)&addr_v4.sin_addr.s_addr,
361 					   &req->addr_info.mAddress);
362 		req->addr_info.mPort = net_ntohs(addr_v4.sin_port);
363 	} else {
364 #endif /* CONFIG_NET_IPV4 */
365 		addrlen = sizeof(addr_v6);
366 		len = zsock_recvfrom(mdns_sock_v6, req->buffer, sizeof(req->buffer), 0,
367 				     (struct net_sockaddr *)&addr_v6, &addrlen);
368 		VerifyOrExit(len > 0);
369 		memcpy(&req->addr_info.mAddress, &addr_v6.sin6_addr,
370 		       sizeof(req->addr_info.mAddress));
371 		req->addr_info.mPort = net_ntohs(addr_v6.sin6_port);
372 #if defined(CONFIG_NET_IPV4)
373 	}
374 #endif /* CONFIG_NET_IPV4 */
375 	req->length = (uint16_t)len;
376 	req->addr_info.mInfraIfIndex = ail_iface_index;
377 	req->cb = process_mdns_message;
378 
379 	openthread_border_router_post_message(req);
380 
381 exit:
382 	return;
383 }
384 
process_mdns_message(struct otbr_msg_ctx * msg_ctx_ptr)385 static void process_mdns_message(struct otbr_msg_ctx *msg_ctx_ptr)
386 {
387 	otMessageSettings ot_message_settings = {true, OT_MESSAGE_PRIORITY_NORMAL};
388 	otMessage *ot_message = NULL;
389 	otBufferInfo buffer_info;
390 	uint16_t req_buff_num;
391 
392 	/** In large networks with high traffic, we have observed that mDNS module
393 	 * might jump to assert when trying to allocate OT message buffers for a new
394 	 * query/response that has to be sent.
395 	 * Here, we calculate the approximate number of OT message buffers that will be required
396 	 * to hold the incoming mDNS packet. If the number of free OT message buffers will drop
397 	 * below the imposed limit after the conversion has been perfomed, the incoming packet
398 	 * will be silently dropped.
399 	 * A possible scenario would be when multipackets (TC bit set) are received from multiple
400 	 * hosts, as mDNS module stores the incoming messages for a period of time.
401 	 * This mechanism tries to make sure that there are enough free buffers for mDNS module
402 	 * to perform it's execution.
403 	 */
404 
405 	req_buff_num = (msg_ctx_ptr->length /
406 			(CONFIG_OPENTHREAD_MESSAGE_BUFFER_SIZE - sizeof(otMessageBuffer))) + 1;
407 	otMessageGetBufferInfo(ot_instance_ptr, &buffer_info);
408 
409 	VerifyOrExit((buffer_info.mFreeBuffers - req_buff_num) >=
410 		     ((PKT_THRESHOLD_VAL * CONFIG_OPENTHREAD_NUM_MESSAGE_BUFFERS) / 100));
411 
412 	ot_message = otIp6NewMessage(ot_instance_ptr, &ot_message_settings);
413 	VerifyOrExit(ot_message);
414 	VerifyOrExit(otMessageAppend(ot_message, msg_ctx_ptr->buffer,
415 				     msg_ctx_ptr->length) == OT_ERROR_NONE);
416 	otPlatMdnsHandleReceive(ot_instance_ptr, ot_message, /* aIsUnicast */ false,
417 				&msg_ctx_ptr->addr_info);
418 	ot_message = NULL;
419 exit:
420 	if (ot_message != NULL) {
421 		otMessageFree(ot_message);
422 	}
423 }
424 
mdns_plat_monitor_interface(struct net_if * ail_iface)425 void mdns_plat_monitor_interface(struct net_if *ail_iface)
426 {
427 	struct net_if_ipv6 *ipv6 = NULL;
428 	otIp6Address ip6_addr = {0};
429 	struct net_if_addr *unicast = NULL;
430 
431 	VerifyOrExit(mdns_socket_is_enabled);
432 
433 	net_if_lock(ail_iface);
434 
435 	otPlatMdnsHandleHostAddressRemoveAll(ot_instance_ptr, ail_iface_index);
436 
437 	ipv6 = ail_iface->config.ip.ipv6;
438 	ARRAY_FOR_EACH(ipv6->unicast, idx) {
439 		unicast = &ipv6->unicast[idx];
440 
441 		if (!unicast->is_used) {
442 			continue;
443 		}
444 		memcpy(&ip6_addr.mFields.m32, &unicast->address.in6_addr.s6_addr32,
445 		       sizeof(otIp6Address));
446 		otPlatMdnsHandleHostAddressEvent(ot_instance_ptr, &ip6_addr, true,
447 						 ail_iface_index);
448 	}
449 
450 #if defined(CONFIG_NET_IPV4) && defined(CONFIG_NET_IPV4_MAPPING_TO_IPV6)
451 	struct net_if_ipv4 *ipv4 = NULL;
452 	otIp4Address ip4_addr = {0};
453 
454 	ipv4 = ail_iface->config.ip.ipv4;
455 	ARRAY_FOR_EACH(ipv4->unicast, idx) {
456 		unicast = &ipv4->unicast[idx].ipv4;
457 
458 		if (!unicast->is_used) {
459 			continue;
460 		}
461 		memcpy(&ip4_addr.mFields.m32, &unicast->address.in_addr.s4_addr32,
462 		       sizeof(otIp4Address));
463 		otIp4ToIp4MappedIp6Address(&ip4_addr, &ip6_addr);
464 		otPlatMdnsHandleHostAddressEvent(ot_instance_ptr, &ip6_addr, true,
465 						 ail_iface_index);
466 	}
467 #endif /* CONFIG_NET_IPV4 && CONFIG_NET_IPV4_MAPPING_TO_IPV6 */
468 
469 	net_if_unlock(ail_iface);
470 exit:
471 	return;
472 }
473