1 /*
2  *  Copyright (c) 2024, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include "platform-simulation.h"
30 
31 #include <openthread/nat64.h>
32 #include <openthread/platform/mdns_socket.h>
33 
34 #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
35 
36 //---------------------------------------------------------------------------------------------------------------------
37 #if OPENTHREAD_SIMULATION_MDNS_SOCKET_IMPLEMENT_POSIX
38 
39 // Provide a simplified POSIX based implementation of `otPlatMdns`
40 // platform APIs. This is intended for testing.
41 
42 #include <openthread/ip6.h>
43 
44 #include <arpa/inet.h>
45 #include <errno.h>
46 #include <net/if.h>
47 #include <netinet/in.h>
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <string.h>
51 #include <sys/socket.h>
52 #include <sys/types.h>
53 
54 #include "simul_utils.h"
55 #include "utils/code_utils.h"
56 
57 #define MAX_BUFFER_SIZE 1600
58 
59 #define MDNS_PORT 5353
60 
61 static bool     sEnabled = false;
62 static uint32_t sInfraIfIndex;
63 static int      sMdnsFd4 = -1;
64 static int      sMdnsFd6 = -1;
65 
66 /* this is a portability hack */
67 #ifndef IPV6_ADD_MEMBERSHIP
68 #ifdef IPV6_JOIN_GROUP
69 #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
70 #endif
71 #endif
72 
73 #ifndef IPV6_DROP_MEMBERSHIP
74 #ifdef IPV6_LEAVE_GROUP
75 #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
76 #endif
77 #endif
78 
79 #define VerifyOrDie(aCondition, aErrMsg)                                        \
80     do                                                                          \
81     {                                                                           \
82         if (!(aCondition))                                                      \
83         {                                                                       \
84             fprintf(stderr, "\n\r" aErrMsg ". errono:%s\n\r", strerror(errno)); \
85             exit(1);                                                            \
86         }                                                                       \
87     } while (false)
88 
SetReuseAddrPort(int aFd)89 static void SetReuseAddrPort(int aFd)
90 {
91     int ret;
92     int yes = 1;
93 
94     ret = setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes));
95     VerifyOrDie(ret >= 0, "setsocketopt(SO_REUSEADDR) failed");
96 
97     ret = setsockopt(aFd, SOL_SOCKET, SO_REUSEPORT, (char *)&yes, sizeof(yes));
98     VerifyOrDie(ret >= 0, "setsocketopt(SO_REUSEPORT) failed");
99 }
100 
OpenIp4Socket(uint32_t aInfraIfIndex)101 static void OpenIp4Socket(uint32_t aInfraIfIndex)
102 {
103     OT_UNUSED_VARIABLE(aInfraIfIndex);
104 
105     struct sockaddr_in addr;
106     int                fd;
107     int                ret;
108     uint8_t            u8;
109     int                value;
110 
111     fd = socket(AF_INET, SOCK_DGRAM, 0);
112     VerifyOrDie(fd >= 0, "socket() failed");
113 
114 #ifdef __linux__
115     {
116         char        nameBuffer[IF_NAMESIZE];
117         const char *ifname;
118 
119         ifname = if_indextoname(aInfraIfIndex, nameBuffer);
120         VerifyOrDie(ifname != NULL, "if_indextoname() failed");
121 
122         ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname));
123         VerifyOrDie(ret >= 0, "setsocketopt(SO_BINDTODEVICE) failed");
124     }
125 #else
126     value = aInfraIfIndex;
127     ret   = setsockopt(fd, IPPROTO_IP, IP_BOUND_IF, &value, sizeof(value));
128 #endif
129 
130     u8  = 255;
131     ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &u8, sizeof(u8));
132     VerifyOrDie(ret >= 0, "setsocketopt(IP_MULTICAST_TTL) failed");
133 
134     value = 255;
135     ret   = setsockopt(fd, IPPROTO_IP, IP_TTL, &value, sizeof(value));
136     VerifyOrDie(ret >= 0, "setsocketopt(IP_TTL) failed");
137 
138     u8  = 1;
139     ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &u8, sizeof(u8));
140     VerifyOrDie(ret >= 0, "setsocketopt(IP_MULTICAST_LOOP) failed");
141 
142     SetReuseAddrPort(fd);
143 
144     {
145         struct ip_mreqn mreqn;
146 
147         memset(&mreqn, 0, sizeof(mreqn));
148         mreqn.imr_multiaddr.s_addr = inet_addr("224.0.0.251");
149         mreqn.imr_ifindex          = aInfraIfIndex;
150 
151         ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &mreqn, sizeof(mreqn));
152         VerifyOrDie(ret >= 0, "setsocketopt(IP_MULTICAST_IF) failed");
153     }
154 
155     memset(&addr, 0, sizeof(addr));
156     addr.sin_family      = AF_INET;
157     addr.sin_addr.s_addr = htonl(INADDR_ANY);
158     addr.sin_port        = htons(MDNS_PORT);
159 
160     ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
161     VerifyOrDie(ret >= 0, "bind() failed");
162 
163     sMdnsFd4 = fd;
164 }
165 
JoinOrLeaveIp4MulticastGroup(bool aJoin,uint32_t aInfraIfIndex)166 static void JoinOrLeaveIp4MulticastGroup(bool aJoin, uint32_t aInfraIfIndex)
167 {
168     struct ip_mreqn mreqn;
169     int             ret;
170 
171     memset(&mreqn, 0, sizeof(mreqn));
172     mreqn.imr_multiaddr.s_addr = inet_addr("224.0.0.251");
173     mreqn.imr_ifindex          = aInfraIfIndex;
174 
175     if (aJoin)
176     {
177         // Suggested workaround for netif not dropping
178         // a previous multicast membership.
179         setsockopt(sMdnsFd4, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreqn, sizeof(mreqn));
180     }
181 
182     ret = setsockopt(sMdnsFd4, IPPROTO_IP, aJoin ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP, &mreqn, sizeof(mreqn));
183     VerifyOrDie(ret >= 0, "setsocketopt(IP_ADD/DROP_MEMBERSHIP) failed");
184 }
185 
OpenIp6Socket(uint32_t aInfraIfIndex)186 static void OpenIp6Socket(uint32_t aInfraIfIndex)
187 {
188     OT_UNUSED_VARIABLE(aInfraIfIndex);
189 
190     struct sockaddr_in6 addr6;
191     int                 fd;
192     int                 ret;
193     int                 value;
194 
195     fd = socket(AF_INET6, SOCK_DGRAM, 0);
196     VerifyOrDie(fd >= 0, "socket() failed");
197 
198 #ifdef __linux__
199     {
200         char        nameBuffer[IF_NAMESIZE];
201         const char *ifname;
202 
203         ifname = if_indextoname(aInfraIfIndex, nameBuffer);
204         VerifyOrDie(ifname != NULL, "if_indextoname() failed");
205 
206         ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname));
207         VerifyOrDie(ret >= 0, "setsocketopt(SO_BINDTODEVICE) failed");
208     }
209 #else
210     value = aInfraIfIndex;
211     ret   = setsockopt(fd, IPPROTO_IPV6, IPV6_BOUND_IF, &value, sizeof(value));
212 #endif
213 
214     value = 255;
215     ret   = setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &value, sizeof(value));
216     VerifyOrDie(ret >= 0, "setsocketopt(IPV6_MULTICAST_HOPS) failed");
217 
218     value = 255;
219     ret   = setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &value, sizeof(value));
220     VerifyOrDie(ret >= 0, "setsocketopt(IPV6_UNICAST_HOPS) failed");
221 
222     value = 1;
223     ret   = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &value, sizeof(value));
224     VerifyOrDie(ret >= 0, "setsocketopt(IPV6_V6ONLY) failed");
225 
226     value = aInfraIfIndex;
227     ret   = setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &value, sizeof(value));
228     VerifyOrDie(ret >= 0, "setsocketopt(IPV6_MULTICAST_IF) failed");
229 
230     value = 1;
231     ret   = setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &value, sizeof(value));
232     VerifyOrDie(ret >= 0, "setsocketopt(IPV6_MULTICAST_LOOP) failed");
233 
234     SetReuseAddrPort(fd);
235 
236     memset(&addr6, 0, sizeof(addr6));
237     addr6.sin6_family = AF_INET6;
238     addr6.sin6_port   = htons(MDNS_PORT);
239 
240     ret = bind(fd, (struct sockaddr *)&addr6, sizeof(addr6));
241     VerifyOrDie(ret >= 0, "bind() failed");
242 
243     sMdnsFd6 = fd;
244 }
245 
JoinOrLeaveIp6MulticastGroup(bool aJoin,uint32_t aInfraIfIndex)246 static void JoinOrLeaveIp6MulticastGroup(bool aJoin, uint32_t aInfraIfIndex)
247 {
248     struct ipv6_mreq mreq6;
249     int              ret;
250 
251     memset(&mreq6, 0, sizeof(mreq6));
252 
253     inet_pton(AF_INET6, "ff02::fb", &mreq6.ipv6mr_multiaddr);
254     mreq6.ipv6mr_interface = (int)aInfraIfIndex;
255 
256     if (aJoin)
257     {
258         // Suggested workaround for netif not dropping
259         // a previous multicast membership.
260         setsockopt(sMdnsFd6, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6));
261     }
262 
263     ret = setsockopt(sMdnsFd6, IPPROTO_IPV6, aJoin ? IPV6_ADD_MEMBERSHIP : IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6));
264     VerifyOrDie(ret >= 0, "setsocketopt(IP6_ADD/DROP_MEMBERSHIP) failed");
265 }
266 
otPlatMdnsSetListeningEnabled(otInstance * aInstance,bool aEnable,uint32_t aInfraIfIndex)267 otError otPlatMdnsSetListeningEnabled(otInstance *aInstance, bool aEnable, uint32_t aInfraIfIndex)
268 {
269     OT_UNUSED_VARIABLE(aInstance);
270 
271     if (aEnable)
272     {
273         otEXPECT(!sEnabled);
274 
275         OpenIp4Socket(aInfraIfIndex);
276         JoinOrLeaveIp4MulticastGroup(/* aJoin */ true, aInfraIfIndex);
277         OpenIp6Socket(aInfraIfIndex);
278         JoinOrLeaveIp6MulticastGroup(/* aJoin */ true, aInfraIfIndex);
279 
280         sEnabled      = true;
281         sInfraIfIndex = aInfraIfIndex;
282     }
283     else
284     {
285         otEXPECT(sEnabled);
286 
287         JoinOrLeaveIp4MulticastGroup(/* aJoin */ false, aInfraIfIndex);
288         JoinOrLeaveIp6MulticastGroup(/* aJoin */ false, aInfraIfIndex);
289         close(sMdnsFd4);
290         close(sMdnsFd6);
291         sEnabled = false;
292     }
293 
294 exit:
295     return OT_ERROR_NONE;
296 }
297 
otPlatMdnsSendMulticast(otInstance * aInstance,otMessage * aMessage,uint32_t aInfraIfIndex)298 void otPlatMdnsSendMulticast(otInstance *aInstance, otMessage *aMessage, uint32_t aInfraIfIndex)
299 {
300     OT_UNUSED_VARIABLE(aInstance);
301     OT_UNUSED_VARIABLE(aInfraIfIndex);
302 
303     uint8_t  buffer[MAX_BUFFER_SIZE];
304     uint16_t length;
305     int      bytes;
306 
307     otEXPECT(sEnabled);
308 
309     length = otMessageRead(aMessage, 0, buffer, sizeof(buffer));
310     otMessageFree(aMessage);
311 
312     {
313         struct sockaddr_in addr;
314 
315         memset(&addr, 0, sizeof(addr));
316         addr.sin_family      = AF_INET;
317         addr.sin_addr.s_addr = inet_addr("224.0.0.251");
318         addr.sin_port        = htons(MDNS_PORT);
319 
320         bytes = sendto(sMdnsFd4, buffer, length, 0, (struct sockaddr *)&addr, sizeof(addr));
321 
322         VerifyOrDie((bytes == length), "sendTo(sMdnsFd4) failed");
323     }
324 
325     {
326         struct sockaddr_in6 addr6;
327 
328         memset(&addr6, 0, sizeof(addr6));
329         addr6.sin6_family = AF_INET6;
330         addr6.sin6_port   = htons(MDNS_PORT);
331         inet_pton(AF_INET6, "ff02::fb", &addr6.sin6_addr);
332 
333         bytes = sendto(sMdnsFd6, buffer, length, 0, (struct sockaddr *)&addr6, sizeof(addr6));
334 
335         VerifyOrDie((bytes == length), "sendTo(sMdnsFd6) failed");
336     }
337 
338 exit:
339     return;
340 }
341 
otPlatMdnsSendUnicast(otInstance * aInstance,otMessage * aMessage,const otPlatMdnsAddressInfo * aAddress)342 void otPlatMdnsSendUnicast(otInstance *aInstance, otMessage *aMessage, const otPlatMdnsAddressInfo *aAddress)
343 {
344     OT_UNUSED_VARIABLE(aInstance);
345 
346     otIp4Address ip4Addr;
347     uint8_t      buffer[MAX_BUFFER_SIZE];
348     uint16_t     length;
349     int          bytes;
350 
351     otEXPECT(sEnabled);
352 
353     length = otMessageRead(aMessage, 0, buffer, sizeof(buffer));
354     otMessageFree(aMessage);
355 
356     if (otIp4FromIp4MappedIp6Address(&aAddress->mAddress, &ip4Addr) == OT_ERROR_NONE)
357     {
358         struct sockaddr_in addr;
359 
360         memset(&addr, 0, sizeof(addr));
361         addr.sin_family = AF_INET;
362         memcpy(&addr.sin_addr.s_addr, &ip4Addr, sizeof(otIp4Address));
363         addr.sin_port = htons(MDNS_PORT);
364 
365         bytes = sendto(sMdnsFd4, buffer, length, 0, (struct sockaddr *)&addr, sizeof(addr));
366 
367         VerifyOrDie((bytes == length), "sendTo(sMdnsFd4) failed");
368     }
369     else
370     {
371         struct sockaddr_in6 addr6;
372 
373         memset(&addr6, 0, sizeof(addr6));
374         addr6.sin6_family = AF_INET6;
375         addr6.sin6_port   = htons(MDNS_PORT);
376         memcpy(&addr6.sin6_addr, &aAddress->mAddress, sizeof(otIp6Address));
377 
378         bytes = sendto(sMdnsFd6, buffer, length, 0, (struct sockaddr *)&addr6, sizeof(addr6));
379 
380         VerifyOrDie((bytes == length), "sendTo(sMdnsFd6) failed");
381     }
382 
383 exit:
384     return;
385 }
386 
platformMdnsSocketUpdateFdSet(fd_set * aReadFdSet,int * aMaxFd)387 void platformMdnsSocketUpdateFdSet(fd_set *aReadFdSet, int *aMaxFd)
388 {
389     otEXPECT(sEnabled);
390 
391     utilsAddFdToFdSet(sMdnsFd4, aReadFdSet, aMaxFd);
392     utilsAddFdToFdSet(sMdnsFd6, aReadFdSet, aMaxFd);
393 
394 exit:
395     return;
396 }
397 
platformMdnsSocketProcess(otInstance * aInstance,const fd_set * aReadFdSet)398 void platformMdnsSocketProcess(otInstance *aInstance, const fd_set *aReadFdSet)
399 {
400     otEXPECT(sEnabled);
401 
402     if (FD_ISSET(sMdnsFd4, aReadFdSet))
403     {
404         uint8_t               buffer[MAX_BUFFER_SIZE];
405         struct sockaddr_in    sockaddr;
406         otPlatMdnsAddressInfo addrInfo;
407         otMessage            *message;
408         socklen_t             len = sizeof(sockaddr);
409         ssize_t               rval;
410 
411         memset(&sockaddr, 0, sizeof(sockaddr));
412         rval = recvfrom(sMdnsFd4, (char *)&buffer, sizeof(buffer), 0, (struct sockaddr *)&sockaddr, &len);
413 
414         VerifyOrDie(rval >= 0, "recvfrom() failed");
415 
416         message = otIp6NewMessage(aInstance, NULL);
417         VerifyOrDie(message != NULL, "otIp6NewMessage() failed");
418 
419         VerifyOrDie(otMessageAppend(message, buffer, (uint16_t)rval) == OT_ERROR_NONE, "otMessageAppend() failed");
420 
421         memset(&addrInfo, 0, sizeof(addrInfo));
422         otIp4ToIp4MappedIp6Address((otIp4Address *)(&sockaddr.sin_addr.s_addr), &addrInfo.mAddress);
423         addrInfo.mPort         = MDNS_PORT;
424         addrInfo.mInfraIfIndex = sInfraIfIndex;
425 
426         otPlatMdnsHandleReceive(aInstance, message, /* aInUnicast */ false, &addrInfo);
427     }
428 
429     if (FD_ISSET(sMdnsFd6, aReadFdSet))
430     {
431         uint8_t               buffer[MAX_BUFFER_SIZE];
432         struct sockaddr_in6   sockaddr6;
433         otPlatMdnsAddressInfo addrInfo;
434         otMessage            *message;
435         socklen_t             len = sizeof(sockaddr6);
436         ssize_t               rval;
437 
438         memset(&sockaddr6, 0, sizeof(sockaddr6));
439         rval = recvfrom(sMdnsFd6, (char *)&buffer, sizeof(buffer), 0, (struct sockaddr *)&sockaddr6, &len);
440         VerifyOrDie(rval >= 0, "recvfrom(sMdnsFd6) failed");
441 
442         message = otIp6NewMessage(aInstance, NULL);
443         VerifyOrDie(message != NULL, "otIp6NewMessage() failed");
444 
445         VerifyOrDie(otMessageAppend(message, buffer, (uint16_t)rval) == OT_ERROR_NONE, "otMessageAppend() failed");
446 
447         memset(&addrInfo, 0, sizeof(addrInfo));
448         memcpy(&addrInfo.mAddress, &sockaddr6.sin6_addr, sizeof(otIp6Address));
449         addrInfo.mPort         = MDNS_PORT;
450         addrInfo.mInfraIfIndex = sInfraIfIndex;
451 
452         otPlatMdnsHandleReceive(aInstance, message, /* aInUnicast */ false, &addrInfo);
453     }
454 
455 exit:
456     return;
457 }
458 
459 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
460 // Add weak implementation of `ot` APIs for RCP build. Note that
461 // `simulation` platform does not get `OPENTHREAD_RADIO` config)
462 
otMessageRead(const otMessage * aMessage,uint16_t aOffset,void * aBuf,uint16_t aLength)463 OT_TOOL_WEAK uint16_t otMessageRead(const otMessage *aMessage, uint16_t aOffset, void *aBuf, uint16_t aLength)
464 {
465     OT_UNUSED_VARIABLE(aMessage);
466     OT_UNUSED_VARIABLE(aOffset);
467     OT_UNUSED_VARIABLE(aBuf);
468     OT_UNUSED_VARIABLE(aLength);
469 
470     fprintf(stderr, "\n\rWeak otMessageRead() is incorrectly used\n\r");
471     exit(1);
472 
473     return 0;
474 }
475 
otMessageFree(otMessage * aMessage)476 OT_TOOL_WEAK void otMessageFree(otMessage *aMessage)
477 {
478     OT_UNUSED_VARIABLE(aMessage);
479     fprintf(stderr, "\n\rWeak otMessageFree() is incorrectly used\n\r");
480     exit(1);
481 }
482 
otIp6NewMessage(otInstance * aInstance,const otMessageSettings * aSettings)483 OT_TOOL_WEAK otMessage *otIp6NewMessage(otInstance *aInstance, const otMessageSettings *aSettings)
484 {
485     OT_UNUSED_VARIABLE(aInstance);
486     OT_UNUSED_VARIABLE(aSettings);
487 
488     fprintf(stderr, "\n\rWeak otIp6NewMessage() is incorrectly used\n\r");
489     exit(1);
490 
491     return NULL;
492 }
493 
otMessageAppend(otMessage * aMessage,const void * aBuf,uint16_t aLength)494 OT_TOOL_WEAK otError otMessageAppend(otMessage *aMessage, const void *aBuf, uint16_t aLength)
495 {
496     OT_UNUSED_VARIABLE(aMessage);
497     OT_UNUSED_VARIABLE(aBuf);
498     OT_UNUSED_VARIABLE(aLength);
499 
500     fprintf(stderr, "\n\rWeak otMessageFree() is incorrectly used\n\r");
501     exit(1);
502 
503     return OT_ERROR_NOT_IMPLEMENTED;
504 }
505 
otIp4ToIp4MappedIp6Address(const otIp4Address * aIp4Address,otIp6Address * aIp6Address)506 OT_TOOL_WEAK void otIp4ToIp4MappedIp6Address(const otIp4Address *aIp4Address, otIp6Address *aIp6Address)
507 {
508     OT_UNUSED_VARIABLE(aIp4Address);
509     OT_UNUSED_VARIABLE(aIp6Address);
510 
511     fprintf(stderr, "\n\rWeak otIp4ToIp4MappedIp6Address() is incorrectly used\n\r");
512     exit(1);
513 }
514 
otIp4FromIp4MappedIp6Address(const otIp6Address * aIp6Address,otIp4Address * aIp4Address)515 OT_TOOL_WEAK otError otIp4FromIp4MappedIp6Address(const otIp6Address *aIp6Address, otIp4Address *aIp4Address)
516 {
517     OT_UNUSED_VARIABLE(aIp6Address);
518     OT_UNUSED_VARIABLE(aIp4Address);
519 
520     fprintf(stderr, "\n\rWeak otIp4FromIp4MappedIp6Address() is incorrectly used\n\r");
521     exit(1);
522 
523     return OT_ERROR_NOT_IMPLEMENTED;
524 }
525 
otPlatMdnsHandleReceive(otInstance * aInstance,otMessage * aMessage,bool aIsUnicast,const otPlatMdnsAddressInfo * aAddress)526 OT_TOOL_WEAK void otPlatMdnsHandleReceive(otInstance                  *aInstance,
527                                           otMessage                   *aMessage,
528                                           bool                         aIsUnicast,
529                                           const otPlatMdnsAddressInfo *aAddress)
530 {
531     OT_UNUSED_VARIABLE(aInstance);
532     OT_UNUSED_VARIABLE(aMessage);
533     OT_UNUSED_VARIABLE(aIsUnicast);
534     OT_UNUSED_VARIABLE(aAddress);
535 
536     fprintf(stderr, "\n\rWeak otPlatMdnsHandleReceive() is incorrectly used\n\r");
537     exit(1);
538 }
539 
540 //---------------------------------------------------------------------------------------------------------------------
541 #else // OPENTHREAD_SIMULATION_MDNS_SOCKET_IMPLEMENT_POSIX
542 
otPlatMdnsSetListeningEnabled(otInstance * aInstance,bool aEnable,uint32_t aInfraIfIndex)543 otError otPlatMdnsSetListeningEnabled(otInstance *aInstance, bool aEnable, uint32_t aInfraIfIndex)
544 {
545     OT_UNUSED_VARIABLE(aInstance);
546     OT_UNUSED_VARIABLE(aEnable);
547     OT_UNUSED_VARIABLE(aInfraIfIndex);
548 
549     return OT_ERROR_NOT_IMPLEMENTED;
550 }
551 
otPlatMdnsSendMulticast(otInstance * aInstance,otMessage * aMessage,uint32_t aInfraIfIndex)552 void otPlatMdnsSendMulticast(otInstance *aInstance, otMessage *aMessage, uint32_t aInfraIfIndex)
553 {
554     OT_UNUSED_VARIABLE(aInstance);
555     OT_UNUSED_VARIABLE(aInfraIfIndex);
556 
557     otMessageFree(aMessage);
558 }
559 
otPlatMdnsSendUnicast(otInstance * aInstance,otMessage * aMessage,const otPlatMdnsAddressInfo * aAddress)560 void otPlatMdnsSendUnicast(otInstance *aInstance, otMessage *aMessage, const otPlatMdnsAddressInfo *aAddress)
561 {
562     OT_UNUSED_VARIABLE(aInstance);
563     OT_UNUSED_VARIABLE(aAddress);
564     otMessageFree(aMessage);
565 }
566 
567 #endif // OPENTHREAD_SIMULATION_MDNS_SOCKET_IMPLEMENT_POSIX
568 
569 #endif // OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
570