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 /**
30  * @file
31  * @brief
32  *   This file includes the platform abstraction for mDNS socket.
33  *
34  */
35 
36 #ifndef OPENTHREAD_PLATFORM_MULTICAST_DNS_SOCKET_H_
37 #define OPENTHREAD_PLATFORM_MULTICAST_DNS_SOCKET_H_
38 
39 #include <stdint.h>
40 
41 #include <openthread/instance.h>
42 #include <openthread/ip6.h>
43 #include <openthread/message.h>
44 
45 #ifdef __cplusplus
46 extern "C" {
47 #endif
48 
49 /**
50  * @addtogroup plat-mdns
51  *
52  * @brief
53  *   This module defines platform APIs for Multicast DNS (mDNS) socket.
54  *
55  * @{
56  *
57  */
58 
59 /**
60  * Represents a socket address info.
61  *
62  */
63 typedef struct otPlatMdnsAddressInfo
64 {
65     otIp6Address mAddress;      ///< IP address. IPv4-mapped IPv6 format should be used to represent IPv4 address.
66     uint16_t     mPort;         ///< Port number.
67     uint32_t     mInfraIfIndex; ///< Interface index.
68 } otPlatMdnsAddressInfo;
69 
70 /**
71  * Enables or disables listening for mDNS messages sent to mDNS port 5353.
72  *
73  * When listening is enabled, the platform MUST listen for multicast messages sent to UDP destination port 5353 at the
74  * mDNS link-local multicast address `224.0.0.251` and its IPv6 equivalent `ff02::fb`.
75  *
76  * The platform SHOULD also listen for any unicast messages sent to UDP destination port 5353. If this is not possible,
77  * then OpenThread mDNS module can be configured to not use any "QU" questions requesting unicast response.
78  *
79  * While enabled, all received messages MUST be reported back using `otPlatMdnsHandleReceive()` callback.
80  *
81  * @param[in] aInstance        The OpernThread instance.
82  * @param[in] aEnable          Indicate whether to enable or disable.
83  * @param[in] aInfraInfIndex   The infrastructure network interface index.
84  *
85  * @retval OT_ERROR_NONE     Successfully enabled/disabled listening for mDNS messages.
86  * @retval OT_ERROR_FAILED   Failed to enable/disable listening for mDNS messages.
87  *
88  */
89 otError otPlatMdnsSetListeningEnabled(otInstance *aInstance, bool aEnable, uint32_t aInfraIfIndex);
90 
91 /**
92  * Sends an mDNS message as multicast.
93  *
94  * The platform MUST multicast the prepared mDNS message in @p aMessage as a UDP message using the mDNS well-known port
95  * number 5353 for both source and destination ports. The message MUST be sent to the mDNS link-local multicast
96  * address `224.0.0.251` and/or its IPv6 equivalent `ff02::fb`.
97  *
98  * @p aMessage contains the mDNS message starting with DNS header at offset zero. It does not include IP or UDP headers.
99  * This function passes the ownership of @p aMessage to the platform layer and platform implementation MUST free
100  * @p aMessage once sent and no longer needed.
101  *
102  * The platform MUST allow multicast loopback, i.e., the multicast message @p aMessage MUST also be received and
103  * passed back to OpenThread stack using `otPlatMdnsHandleReceive()` callback. This behavior is essential for the
104  * OpenThread mDNS stack to process and potentially respond to its own queries, while allowing other mDNS receivers
105  * to also receive the query and its response.
106  *
107  * @param[in] aInstance       The OpenThread instance.
108  * @param[in] aMessage        The mDNS message to multicast. Ownership is transferred to the platform layer.
109  * @param[in] aInfraIfIndex   The infrastructure network interface index.
110  *
111  */
112 void otPlatMdnsSendMulticast(otInstance *aInstance, otMessage *aMessage, uint32_t aInfraIfIndex);
113 
114 /**
115  * Sends an mDNS message as unicast.
116  *
117  * The platform MUST send the prepared mDNS message in @p aMessage as a UDP message using source UDP port 5353 to
118  * the destination address and port number specified by @p aAddress.
119  *
120  * @p aMessage contains the DNS message starting with the DNS header at offset zero. It does not include IP or UDP
121  * headers. This function passes the ownership of @p aMessage to the platform layer and platform implementation
122  * MUST free @p aMessage once sent and no longer needed.
123  *
124  * The @p aAddress fields are as follows:
125  *
126  * - `mAddress` specifies the destination address. IPv4-mapped IPv6 format is used to represent an IPv4 destination.
127  * - `mPort` specifies the destination port.
128  * - `mInfraIndex` specifies the interface index.
129  *
130  * If the @aAddress matches this devices address, the platform MUST ensure to receive and pass the message back to
131  * the OpenThread stack using `otPlatMdnsHandleReceive()` for processing.
132  *
133  * @param[in] aInstance   The OpenThread instance.
134  * @param[in] aMessage    The mDNS message to multicast. Ownership is transferred to platform layer.
135  * @param[in] aAddress    The destination address info.
136  *
137  */
138 void otPlatMdnsSendUnicast(otInstance *aInstance, otMessage *aMessage, const otPlatMdnsAddressInfo *aAddress);
139 
140 /**
141  * Callback to notify OpenThread mDNS module of a received message on UDP port 5353.
142  *
143  * @p aMessage MUST contain DNS message starting with the DNS header at offset zero. This function passes the
144  * ownership of @p aMessage from the platform layer to the OpenThread stack. The OpenThread stack will free the
145  * message once processed.
146  *
147  * The @p aAddress fields are as follows:
148  *
149  * - `mAddress` specifies the sender's address. IPv4-mapped IPv6 format is used to represent an IPv4 destination.
150  * - `mPort` specifies the sender's port.
151  * - `mInfraIndex` specifies the interface index.
152  *
153  * @param[in] aInstance    The OpenThread instance.
154  * @param[in] aMessage     The received mDNS message. Ownership is transferred to the OpenThread stack.
155  * @param[in] aIsUnicast   Indicates whether the received message is unicast or multicast.
156  * @param[in] aAddress     The sender's address info.
157  *
158  */
159 extern void otPlatMdnsHandleReceive(otInstance                  *aInstance,
160                                     otMessage                   *aMessage,
161                                     bool                         aIsUnicast,
162                                     const otPlatMdnsAddressInfo *aAddress);
163 
164 /**
165  * @}
166  *
167  */
168 
169 #ifdef __cplusplus
170 } // extern "C"
171 #endif
172 
173 #endif // OPENTHREAD_PLATFORM_MULTICAST_DNS_SOCKET_H_
174