• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "lib/platform/exit_code.h"
56 #include "utils/code_utils.h"
57 
58 #define MAX_BUFFER_SIZE 1600
59 
60 #define MDNS_PORT 5353
61 
62 static bool     sEnabled = false;
63 static uint32_t sInfraIfIndex;
64 static int      sMdnsFd4 = -1;
65 static int      sMdnsFd6 = -1;
66 
67 /* this is a portability hack */
68 #ifndef IPV6_ADD_MEMBERSHIP
69 #ifdef IPV6_JOIN_GROUP
70 #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
71 #endif
72 #endif
73 
74 #ifndef IPV6_DROP_MEMBERSHIP
75 #ifdef IPV6_LEAVE_GROUP
76 #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
77 #endif
78 #endif
79 
SetReuseAddrPort(int aFd)80 static void SetReuseAddrPort(int aFd)
81 {
82     int ret;
83     int yes = 1;
84 
85     ret = setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes));
86     VerifyOrDie(ret >= 0, OT_EXIT_FAILURE);
87 
88     ret = setsockopt(aFd, SOL_SOCKET, SO_REUSEPORT, (char *)&yes, sizeof(yes));
89     VerifyOrDie(ret >= 0, OT_EXIT_FAILURE);
90 }
91 
OpenIp4Socket(uint32_t aInfraIfIndex)92 static void OpenIp4Socket(uint32_t aInfraIfIndex)
93 {
94     OT_UNUSED_VARIABLE(aInfraIfIndex);
95 
96     struct sockaddr_in addr;
97     int                fd;
98     int                ret;
99     uint8_t            u8;
100     int                value;
101 
102     fd = socket(AF_INET, SOCK_DGRAM, 0);
103     VerifyOrDie(fd >= 0, OT_EXIT_FAILURE);
104 
105 #ifdef __linux__
106     {
107         char        nameBuffer[IF_NAMESIZE];
108         const char *ifname;
109 
110         ifname = if_indextoname(aInfraIfIndex, nameBuffer);
111         VerifyOrDie(ifname != NULL, OT_EXIT_ERROR_ERRNO);
112 
113         ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname));
114         VerifyOrDie(ret >= 0, OT_EXIT_ERROR_ERRNO);
115     }
116 #else
117     value = aInfraIfIndex;
118     ret   = setsockopt(fd, IPPROTO_IP, IP_BOUND_IF, &value, sizeof(value));
119 #endif
120 
121     u8  = 255;
122     ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &u8, sizeof(u8));
123     VerifyOrDie(ret >= 0, OT_EXIT_ERROR_ERRNO);
124 
125     value = 255;
126     ret   = setsockopt(fd, IPPROTO_IP, IP_TTL, &value, sizeof(value));
127     VerifyOrDie(ret >= 0, OT_EXIT_ERROR_ERRNO);
128 
129     u8  = 1;
130     ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &u8, sizeof(u8));
131     VerifyOrDie(ret >= 0, OT_EXIT_ERROR_ERRNO);
132 
133     SetReuseAddrPort(fd);
134 
135     {
136         struct ip_mreqn mreqn;
137 
138         memset(&mreqn, 0, sizeof(mreqn));
139         mreqn.imr_multiaddr.s_addr = inet_addr("224.0.0.251");
140         mreqn.imr_ifindex          = aInfraIfIndex;
141 
142         ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &mreqn, sizeof(mreqn));
143         VerifyOrDie(ret >= 0, OT_EXIT_ERROR_ERRNO);
144     }
145 
146     memset(&addr, 0, sizeof(addr));
147     addr.sin_family      = AF_INET;
148     addr.sin_addr.s_addr = htonl(INADDR_ANY);
149     addr.sin_port        = htons(MDNS_PORT);
150 
151     ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
152     VerifyOrDie(ret >= 0, OT_EXIT_ERROR_ERRNO);
153 
154     sMdnsFd4 = fd;
155 }
156 
JoinOrLeaveIp4MulticastGroup(bool aJoin,uint32_t aInfraIfIndex)157 static void JoinOrLeaveIp4MulticastGroup(bool aJoin, uint32_t aInfraIfIndex)
158 {
159     struct ip_mreqn mreqn;
160     int             ret;
161 
162     memset(&mreqn, 0, sizeof(mreqn));
163     mreqn.imr_multiaddr.s_addr = inet_addr("224.0.0.251");
164     mreqn.imr_ifindex          = aInfraIfIndex;
165 
166     if (aJoin)
167     {
168         // Suggested workaround for netif not dropping
169         // a previous multicast membership.
170         setsockopt(sMdnsFd4, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreqn, sizeof(mreqn));
171     }
172 
173     ret = setsockopt(sMdnsFd4, IPPROTO_IP, aJoin ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP, &mreqn, sizeof(mreqn));
174     VerifyOrDie(ret >= 0, OT_EXIT_ERROR_ERRNO);
175 }
176 
OpenIp6Socket(uint32_t aInfraIfIndex)177 static void OpenIp6Socket(uint32_t aInfraIfIndex)
178 {
179     OT_UNUSED_VARIABLE(aInfraIfIndex);
180 
181     struct sockaddr_in6 addr6;
182     int                 fd;
183     int                 ret;
184     int                 value;
185 
186     fd = socket(AF_INET6, SOCK_DGRAM, 0);
187     VerifyOrDie(fd >= 0, OT_EXIT_ERROR_ERRNO);
188 
189 #ifdef __linux__
190     {
191         char        nameBuffer[IF_NAMESIZE];
192         const char *ifname;
193 
194         ifname = if_indextoname(aInfraIfIndex, nameBuffer);
195         VerifyOrDie(ifname != NULL, OT_EXIT_ERROR_ERRNO);
196 
197         ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname));
198         VerifyOrDie(ret >= 0, OT_EXIT_ERROR_ERRNO);
199     }
200 #else
201     value = aInfraIfIndex;
202     ret   = setsockopt(fd, IPPROTO_IPV6, IPV6_BOUND_IF, &value, sizeof(value));
203 #endif
204 
205     value = 255;
206     ret   = setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &value, sizeof(value));
207     VerifyOrDie(ret >= 0, OT_EXIT_ERROR_ERRNO);
208 
209     value = 255;
210     ret   = setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &value, sizeof(value));
211     VerifyOrDie(ret >= 0, OT_EXIT_ERROR_ERRNO);
212 
213     value = 1;
214     ret   = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &value, sizeof(value));
215     VerifyOrDie(ret >= 0, OT_EXIT_ERROR_ERRNO);
216 
217     value = aInfraIfIndex;
218     ret   = setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &value, sizeof(value));
219     VerifyOrDie(ret >= 0, OT_EXIT_ERROR_ERRNO);
220 
221     value = 1;
222     ret   = setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &value, sizeof(value));
223     VerifyOrDie(ret >= 0, OT_EXIT_ERROR_ERRNO);
224 
225     SetReuseAddrPort(fd);
226 
227     memset(&addr6, 0, sizeof(addr6));
228     addr6.sin6_family = AF_INET6;
229     addr6.sin6_port   = htons(MDNS_PORT);
230 
231     ret = bind(fd, (struct sockaddr *)&addr6, sizeof(addr6));
232     VerifyOrDie(ret >= 0, OT_EXIT_ERROR_ERRNO);
233 
234     sMdnsFd6 = fd;
235 }
236 
JoinOrLeaveIp6MulticastGroup(bool aJoin,uint32_t aInfraIfIndex)237 static void JoinOrLeaveIp6MulticastGroup(bool aJoin, uint32_t aInfraIfIndex)
238 {
239     struct ipv6_mreq mreq6;
240     int              ret;
241 
242     memset(&mreq6, 0, sizeof(mreq6));
243 
244     inet_pton(AF_INET6, "ff02::fb", &mreq6.ipv6mr_multiaddr);
245     mreq6.ipv6mr_interface = (int)aInfraIfIndex;
246 
247     if (aJoin)
248     {
249         // Suggested workaround for netif not dropping
250         // a previous multicast membership.
251         setsockopt(sMdnsFd6, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6));
252     }
253 
254     ret = setsockopt(sMdnsFd6, IPPROTO_IPV6, aJoin ? IPV6_ADD_MEMBERSHIP : IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6));
255     VerifyOrDie(ret >= 0, OT_EXIT_ERROR_ERRNO);
256 }
257 
otPlatMdnsSetListeningEnabled(otInstance * aInstance,bool aEnable,uint32_t aInfraIfIndex)258 otError otPlatMdnsSetListeningEnabled(otInstance *aInstance, bool aEnable, uint32_t aInfraIfIndex)
259 {
260     OT_UNUSED_VARIABLE(aInstance);
261 
262     if (aEnable)
263     {
264         otEXPECT(!sEnabled);
265 
266         OpenIp4Socket(aInfraIfIndex);
267         JoinOrLeaveIp4MulticastGroup(/* aJoin */ true, aInfraIfIndex);
268         OpenIp6Socket(aInfraIfIndex);
269         JoinOrLeaveIp6MulticastGroup(/* aJoin */ true, aInfraIfIndex);
270 
271         sEnabled      = true;
272         sInfraIfIndex = aInfraIfIndex;
273     }
274     else
275     {
276         otEXPECT(sEnabled);
277 
278         JoinOrLeaveIp4MulticastGroup(/* aJoin */ false, aInfraIfIndex);
279         JoinOrLeaveIp6MulticastGroup(/* aJoin */ false, aInfraIfIndex);
280         close(sMdnsFd4);
281         close(sMdnsFd6);
282         sEnabled = false;
283     }
284 
285 exit:
286     return OT_ERROR_NONE;
287 }
288 
otPlatMdnsSendMulticast(otInstance * aInstance,otMessage * aMessage,uint32_t aInfraIfIndex)289 void otPlatMdnsSendMulticast(otInstance *aInstance, otMessage *aMessage, uint32_t aInfraIfIndex)
290 {
291     OT_UNUSED_VARIABLE(aInstance);
292     OT_UNUSED_VARIABLE(aInfraIfIndex);
293 
294     uint8_t  buffer[MAX_BUFFER_SIZE];
295     uint16_t length;
296     int      bytes;
297 
298     otEXPECT(sEnabled);
299 
300     length = otMessageRead(aMessage, 0, buffer, sizeof(buffer));
301     otMessageFree(aMessage);
302 
303     {
304         struct sockaddr_in addr;
305 
306         memset(&addr, 0, sizeof(addr));
307         addr.sin_family      = AF_INET;
308         addr.sin_addr.s_addr = inet_addr("224.0.0.251");
309         addr.sin_port        = htons(MDNS_PORT);
310 
311         bytes = sendto(sMdnsFd4, buffer, length, 0, (struct sockaddr *)&addr, sizeof(addr));
312 
313         VerifyOrDie(bytes == length, OT_EXIT_ERROR_ERRNO);
314     }
315 
316     {
317         struct sockaddr_in6 addr6;
318 
319         memset(&addr6, 0, sizeof(addr6));
320         addr6.sin6_family = AF_INET6;
321         addr6.sin6_port   = htons(MDNS_PORT);
322         inet_pton(AF_INET6, "ff02::fb", &addr6.sin6_addr);
323 
324         bytes = sendto(sMdnsFd6, buffer, length, 0, (struct sockaddr *)&addr6, sizeof(addr6));
325 
326         VerifyOrDie(bytes == length, OT_EXIT_ERROR_ERRNO);
327     }
328 
329 exit:
330     return;
331 }
332 
otPlatMdnsSendUnicast(otInstance * aInstance,otMessage * aMessage,const otPlatMdnsAddressInfo * aAddress)333 void otPlatMdnsSendUnicast(otInstance *aInstance, otMessage *aMessage, const otPlatMdnsAddressInfo *aAddress)
334 {
335     OT_UNUSED_VARIABLE(aInstance);
336 
337     otIp4Address ip4Addr;
338     uint8_t      buffer[MAX_BUFFER_SIZE];
339     uint16_t     length;
340     int          bytes;
341 
342     otEXPECT(sEnabled);
343 
344     length = otMessageRead(aMessage, 0, buffer, sizeof(buffer));
345     otMessageFree(aMessage);
346 
347     if (otIp4FromIp4MappedIp6Address(&aAddress->mAddress, &ip4Addr) == OT_ERROR_NONE)
348     {
349         struct sockaddr_in addr;
350 
351         memset(&addr, 0, sizeof(addr));
352         addr.sin_family = AF_INET;
353         memcpy(&addr.sin_addr.s_addr, &ip4Addr, sizeof(otIp4Address));
354         addr.sin_port = htons(MDNS_PORT);
355 
356         bytes = sendto(sMdnsFd4, buffer, length, 0, (struct sockaddr *)&addr, sizeof(addr));
357 
358         VerifyOrDie(bytes == length, OT_EXIT_ERROR_ERRNO);
359     }
360     else
361     {
362         struct sockaddr_in6 addr6;
363 
364         memset(&addr6, 0, sizeof(addr6));
365         addr6.sin6_family = AF_INET6;
366         addr6.sin6_port   = htons(MDNS_PORT);
367         memcpy(&addr6.sin6_addr, &aAddress->mAddress, sizeof(otIp6Address));
368 
369         bytes = sendto(sMdnsFd6, buffer, length, 0, (struct sockaddr *)&addr6, sizeof(addr6));
370 
371         VerifyOrDie(bytes == length, OT_EXIT_ERROR_ERRNO);
372     }
373 
374 exit:
375     return;
376 }
377 
platformMdnsSocketUpdateFdSet(fd_set * aReadFdSet,int * aMaxFd)378 void platformMdnsSocketUpdateFdSet(fd_set *aReadFdSet, int *aMaxFd)
379 {
380     otEXPECT(sEnabled);
381 
382     utilsAddFdToFdSet(sMdnsFd4, aReadFdSet, aMaxFd);
383     utilsAddFdToFdSet(sMdnsFd6, aReadFdSet, aMaxFd);
384 
385 exit:
386     return;
387 }
388 
platformMdnsSocketProcess(otInstance * aInstance,const fd_set * aReadFdSet)389 void platformMdnsSocketProcess(otInstance *aInstance, const fd_set *aReadFdSet)
390 {
391     otEXPECT(sEnabled);
392 
393     if (FD_ISSET(sMdnsFd4, aReadFdSet))
394     {
395         uint8_t               buffer[MAX_BUFFER_SIZE];
396         struct sockaddr_in    sockaddr;
397         otPlatMdnsAddressInfo addrInfo;
398         otMessage            *message;
399         socklen_t             len = sizeof(sockaddr);
400         ssize_t               rval;
401 
402         memset(&sockaddr, 0, sizeof(sockaddr));
403         rval = recvfrom(sMdnsFd4, (char *)&buffer, sizeof(buffer), 0, (struct sockaddr *)&sockaddr, &len);
404 
405         VerifyOrDie(rval >= 0, OT_EXIT_ERROR_ERRNO);
406 
407         message = otIp6NewMessage(aInstance, NULL);
408         VerifyOrDie(message != NULL, OT_EXIT_FAILURE);
409 
410         VerifyOrDie(otMessageAppend(message, buffer, (uint16_t)rval) == OT_ERROR_NONE, OT_EXIT_FAILURE);
411 
412         memset(&addrInfo, 0, sizeof(addrInfo));
413         otIp4ToIp4MappedIp6Address((otIp4Address *)(&sockaddr.sin_addr.s_addr), &addrInfo.mAddress);
414         addrInfo.mPort         = MDNS_PORT;
415         addrInfo.mInfraIfIndex = sInfraIfIndex;
416 
417         otPlatMdnsHandleReceive(aInstance, message, /* aInUnicast */ false, &addrInfo);
418     }
419 
420     if (FD_ISSET(sMdnsFd6, aReadFdSet))
421     {
422         uint8_t               buffer[MAX_BUFFER_SIZE];
423         struct sockaddr_in6   sockaddr6;
424         otPlatMdnsAddressInfo addrInfo;
425         otMessage            *message;
426         socklen_t             len = sizeof(sockaddr6);
427         ssize_t               rval;
428 
429         memset(&sockaddr6, 0, sizeof(sockaddr6));
430         rval = recvfrom(sMdnsFd6, (char *)&buffer, sizeof(buffer), 0, (struct sockaddr *)&sockaddr6, &len);
431         VerifyOrDie(rval >= 0, OT_EXIT_ERROR_ERRNO);
432 
433         message = otIp6NewMessage(aInstance, NULL);
434         VerifyOrDie(message != NULL, OT_EXIT_FAILURE);
435 
436         VerifyOrDie(otMessageAppend(message, buffer, (uint16_t)rval) == OT_ERROR_NONE, OT_EXIT_FAILURE);
437 
438         memset(&addrInfo, 0, sizeof(addrInfo));
439         memcpy(&addrInfo.mAddress, &sockaddr6.sin6_addr, sizeof(otIp6Address));
440         addrInfo.mPort         = MDNS_PORT;
441         addrInfo.mInfraIfIndex = sInfraIfIndex;
442 
443         otPlatMdnsHandleReceive(aInstance, message, /* aInUnicast */ false, &addrInfo);
444     }
445 
446 exit:
447     return;
448 }
449 
450 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
451 // Add weak implementation of `ot` APIs for RCP build. Note that
452 // `simulation` platform does not get `OPENTHREAD_RADIO` config)
453 
otMessageRead(const otMessage * aMessage,uint16_t aOffset,void * aBuf,uint16_t aLength)454 OT_TOOL_WEAK uint16_t otMessageRead(const otMessage *aMessage, uint16_t aOffset, void *aBuf, uint16_t aLength)
455 {
456     OT_UNUSED_VARIABLE(aMessage);
457     OT_UNUSED_VARIABLE(aOffset);
458     OT_UNUSED_VARIABLE(aBuf);
459     OT_UNUSED_VARIABLE(aLength);
460 
461     fprintf(stderr, "\n\rWeak otMessageRead() is incorrectly used\n\r");
462     DieNow(OT_EXIT_FAILURE);
463     return 0;
464 }
465 
otMessageFree(otMessage * aMessage)466 OT_TOOL_WEAK void otMessageFree(otMessage *aMessage)
467 {
468     OT_UNUSED_VARIABLE(aMessage);
469     fprintf(stderr, "\n\rWeak otMessageFree() is incorrectly used\n\r");
470     DieNow(OT_EXIT_FAILURE);
471 }
472 
otIp6NewMessage(otInstance * aInstance,const otMessageSettings * aSettings)473 OT_TOOL_WEAK otMessage *otIp6NewMessage(otInstance *aInstance, const otMessageSettings *aSettings)
474 {
475     OT_UNUSED_VARIABLE(aInstance);
476     OT_UNUSED_VARIABLE(aSettings);
477 
478     fprintf(stderr, "\n\rWeak otIp6NewMessage() is incorrectly used\n\r");
479     DieNow(OT_EXIT_FAILURE);
480 
481     return NULL;
482 }
483 
otMessageAppend(otMessage * aMessage,const void * aBuf,uint16_t aLength)484 OT_TOOL_WEAK otError otMessageAppend(otMessage *aMessage, const void *aBuf, uint16_t aLength)
485 {
486     OT_UNUSED_VARIABLE(aMessage);
487     OT_UNUSED_VARIABLE(aBuf);
488     OT_UNUSED_VARIABLE(aLength);
489 
490     fprintf(stderr, "\n\rWeak otMessageFree() is incorrectly used\n\r");
491     DieNow(OT_EXIT_FAILURE);
492 
493     return OT_ERROR_NOT_IMPLEMENTED;
494 }
495 
otIp4ToIp4MappedIp6Address(const otIp4Address * aIp4Address,otIp6Address * aIp6Address)496 OT_TOOL_WEAK void otIp4ToIp4MappedIp6Address(const otIp4Address *aIp4Address, otIp6Address *aIp6Address)
497 {
498     OT_UNUSED_VARIABLE(aIp4Address);
499     OT_UNUSED_VARIABLE(aIp6Address);
500 
501     fprintf(stderr, "\n\rWeak otIp4ToIp4MappedIp6Address() is incorrectly used\n\r");
502     DieNow(OT_EXIT_FAILURE);
503 }
504 
otIp4FromIp4MappedIp6Address(const otIp6Address * aIp6Address,otIp4Address * aIp4Address)505 OT_TOOL_WEAK otError otIp4FromIp4MappedIp6Address(const otIp6Address *aIp6Address, otIp4Address *aIp4Address)
506 {
507     OT_UNUSED_VARIABLE(aIp6Address);
508     OT_UNUSED_VARIABLE(aIp4Address);
509 
510     fprintf(stderr, "\n\rWeak otIp4FromIp4MappedIp6Address() is incorrectly used\n\r");
511     DieNow(OT_EXIT_FAILURE);
512 
513     return OT_ERROR_NOT_IMPLEMENTED;
514 }
515 
otPlatMdnsHandleReceive(otInstance * aInstance,otMessage * aMessage,bool aIsUnicast,const otPlatMdnsAddressInfo * aAddress)516 OT_TOOL_WEAK void otPlatMdnsHandleReceive(otInstance                  *aInstance,
517                                           otMessage                   *aMessage,
518                                           bool                         aIsUnicast,
519                                           const otPlatMdnsAddressInfo *aAddress)
520 {
521     OT_UNUSED_VARIABLE(aInstance);
522     OT_UNUSED_VARIABLE(aMessage);
523     OT_UNUSED_VARIABLE(aIsUnicast);
524     OT_UNUSED_VARIABLE(aAddress);
525 
526     fprintf(stderr, "\n\rWeak otPlatMdnsHandleReceive() is incorrectly used\n\r");
527     DieNow(OT_EXIT_FAILURE);
528 }
529 
530 //---------------------------------------------------------------------------------------------------------------------
531 #else // OPENTHREAD_SIMULATION_MDNS_SOCKET_IMPLEMENT_POSIX
532 
otPlatMdnsSetListeningEnabled(otInstance * aInstance,bool aEnable,uint32_t aInfraIfIndex)533 otError otPlatMdnsSetListeningEnabled(otInstance *aInstance, bool aEnable, uint32_t aInfraIfIndex)
534 {
535     OT_UNUSED_VARIABLE(aInstance);
536     OT_UNUSED_VARIABLE(aEnable);
537     OT_UNUSED_VARIABLE(aInfraIfIndex);
538 
539     return OT_ERROR_NOT_IMPLEMENTED;
540 }
541 
otPlatMdnsSendMulticast(otInstance * aInstance,otMessage * aMessage,uint32_t aInfraIfIndex)542 void otPlatMdnsSendMulticast(otInstance *aInstance, otMessage *aMessage, uint32_t aInfraIfIndex)
543 {
544     OT_UNUSED_VARIABLE(aInstance);
545     OT_UNUSED_VARIABLE(aInfraIfIndex);
546 
547     otMessageFree(aMessage);
548 }
549 
otPlatMdnsSendUnicast(otInstance * aInstance,otMessage * aMessage,const otPlatMdnsAddressInfo * aAddress)550 void otPlatMdnsSendUnicast(otInstance *aInstance, otMessage *aMessage, const otPlatMdnsAddressInfo *aAddress)
551 {
552     OT_UNUSED_VARIABLE(aInstance);
553     OT_UNUSED_VARIABLE(aAddress);
554     otMessageFree(aMessage);
555 }
556 
557 #endif // OPENTHREAD_SIMULATION_MDNS_SOCKET_IMPLEMENT_POSIX
558 
559 #endif // OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
560