1 /*
2  *  Copyright (c) 2016, 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  *   This file implements the OpenThread IPv6 API.
32  */
33 
34 #include "openthread-core-config.h"
35 
36 #include <openthread/ip6.h>
37 
38 #include "common/instance.hpp"
39 #include "common/locator_getters.hpp"
40 #include "common/logging.hpp"
41 #if OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
42 #include "utils/slaac_address.hpp"
43 #endif
44 
45 using namespace ot;
46 
otIp6SetEnabled(otInstance * aInstance,bool aEnabled)47 otError otIp6SetEnabled(otInstance *aInstance, bool aEnabled)
48 {
49     Error     error    = kErrorNone;
50     Instance &instance = *static_cast<Instance *>(aInstance);
51 
52 #if OPENTHREAD_CONFIG_LINK_RAW_ENABLE
53     VerifyOrExit(!instance.Get<Mac::LinkRaw>().IsEnabled(), error = kErrorInvalidState);
54 #endif
55 
56     if (aEnabled)
57     {
58         instance.Get<ThreadNetif>().Up();
59     }
60     else
61     {
62         instance.Get<ThreadNetif>().Down();
63     }
64 
65 #if OPENTHREAD_CONFIG_LINK_RAW_ENABLE
66 exit:
67 #endif
68     return error;
69 }
70 
otIp6IsEnabled(otInstance * aInstance)71 bool otIp6IsEnabled(otInstance *aInstance)
72 {
73     Instance &instance = *static_cast<Instance *>(aInstance);
74 
75     return instance.Get<ThreadNetif>().IsUp();
76 }
77 
otIp6GetUnicastAddresses(otInstance * aInstance)78 const otNetifAddress *otIp6GetUnicastAddresses(otInstance *aInstance)
79 {
80     Instance &instance = *static_cast<Instance *>(aInstance);
81 
82     return instance.Get<ThreadNetif>().GetUnicastAddresses().GetHead();
83 }
84 
otIp6AddUnicastAddress(otInstance * aInstance,const otNetifAddress * aAddress)85 otError otIp6AddUnicastAddress(otInstance *aInstance, const otNetifAddress *aAddress)
86 {
87     Instance &instance = *static_cast<Instance *>(aInstance);
88 
89     return instance.Get<ThreadNetif>().AddExternalUnicastAddress(
90         *static_cast<const Ip6::Netif::UnicastAddress *>(aAddress));
91 }
92 
otIp6RemoveUnicastAddress(otInstance * aInstance,const otIp6Address * aAddress)93 otError otIp6RemoveUnicastAddress(otInstance *aInstance, const otIp6Address *aAddress)
94 {
95     Instance &instance = *static_cast<Instance *>(aInstance);
96 
97     return instance.Get<ThreadNetif>().RemoveExternalUnicastAddress(*static_cast<const Ip6::Address *>(aAddress));
98 }
99 
otIp6GetMulticastAddresses(otInstance * aInstance)100 const otNetifMulticastAddress *otIp6GetMulticastAddresses(otInstance *aInstance)
101 {
102     Instance &instance = *static_cast<Instance *>(aInstance);
103 
104     return instance.Get<ThreadNetif>().GetMulticastAddresses().GetHead();
105 }
106 
otIp6SubscribeMulticastAddress(otInstance * aInstance,const otIp6Address * aAddress)107 otError otIp6SubscribeMulticastAddress(otInstance *aInstance, const otIp6Address *aAddress)
108 {
109     Instance &instance = *static_cast<Instance *>(aInstance);
110 
111     return instance.Get<ThreadNetif>().SubscribeExternalMulticast(*static_cast<const Ip6::Address *>(aAddress));
112 }
113 
otIp6UnsubscribeMulticastAddress(otInstance * aInstance,const otIp6Address * aAddress)114 otError otIp6UnsubscribeMulticastAddress(otInstance *aInstance, const otIp6Address *aAddress)
115 {
116     Instance &instance = *static_cast<Instance *>(aInstance);
117 
118     return instance.Get<ThreadNetif>().UnsubscribeExternalMulticast(*static_cast<const Ip6::Address *>(aAddress));
119 }
120 
otIp6IsMulticastPromiscuousEnabled(otInstance * aInstance)121 bool otIp6IsMulticastPromiscuousEnabled(otInstance *aInstance)
122 {
123     Instance &instance = *static_cast<Instance *>(aInstance);
124 
125     return instance.Get<ThreadNetif>().IsMulticastPromiscuousEnabled();
126 }
127 
otIp6SetMulticastPromiscuousEnabled(otInstance * aInstance,bool aEnabled)128 void otIp6SetMulticastPromiscuousEnabled(otInstance *aInstance, bool aEnabled)
129 {
130     Instance &instance = *static_cast<Instance *>(aInstance);
131 
132     instance.Get<ThreadNetif>().SetMulticastPromiscuous(aEnabled);
133 }
134 
otIp6SetReceiveCallback(otInstance * aInstance,otIp6ReceiveCallback aCallback,void * aCallbackContext)135 void otIp6SetReceiveCallback(otInstance *aInstance, otIp6ReceiveCallback aCallback, void *aCallbackContext)
136 {
137     Instance &instance = *static_cast<Instance *>(aInstance);
138 
139     instance.Get<Ip6::Ip6>().SetReceiveDatagramCallback(aCallback, aCallbackContext);
140 }
141 
otIp6SetAddressCallback(otInstance * aInstance,otIp6AddressCallback aCallback,void * aCallbackContext)142 void otIp6SetAddressCallback(otInstance *aInstance, otIp6AddressCallback aCallback, void *aCallbackContext)
143 {
144     Instance &instance = *static_cast<Instance *>(aInstance);
145 
146     instance.Get<ThreadNetif>().SetAddressCallback(aCallback, aCallbackContext);
147 }
148 
otIp6IsReceiveFilterEnabled(otInstance * aInstance)149 bool otIp6IsReceiveFilterEnabled(otInstance *aInstance)
150 {
151     Instance &instance = *static_cast<Instance *>(aInstance);
152 
153     return instance.Get<Ip6::Ip6>().IsReceiveIp6FilterEnabled();
154 }
155 
otIp6SetReceiveFilterEnabled(otInstance * aInstance,bool aEnabled)156 void otIp6SetReceiveFilterEnabled(otInstance *aInstance, bool aEnabled)
157 {
158     Instance &instance = *static_cast<Instance *>(aInstance);
159 
160     instance.Get<Ip6::Ip6>().SetReceiveIp6FilterEnabled(aEnabled);
161 }
162 
otIp6Send(otInstance * aInstance,otMessage * aMessage)163 otError otIp6Send(otInstance *aInstance, otMessage *aMessage)
164 {
165     Instance &instance = *static_cast<Instance *>(aInstance);
166 
167     return instance.Get<Ip6::Ip6>().SendRaw(*static_cast<Message *>(aMessage));
168 }
169 
otIp6NewMessage(otInstance * aInstance,const otMessageSettings * aSettings)170 otMessage *otIp6NewMessage(otInstance *aInstance, const otMessageSettings *aSettings)
171 {
172     Instance &instance = *static_cast<Instance *>(aInstance);
173 
174     return instance.Get<Ip6::Ip6>().NewMessage(0, Message::Settings(aSettings));
175 }
176 
otIp6NewMessageFromBuffer(otInstance * aInstance,const uint8_t * aData,uint16_t aDataLength,const otMessageSettings * aSettings)177 otMessage *otIp6NewMessageFromBuffer(otInstance *             aInstance,
178                                      const uint8_t *          aData,
179                                      uint16_t                 aDataLength,
180                                      const otMessageSettings *aSettings)
181 {
182     Instance &instance = *static_cast<Instance *>(aInstance);
183     Message * message;
184 
185     if (aSettings != nullptr)
186     {
187         message = instance.Get<Ip6::Ip6>().NewMessage(aData, aDataLength, Message::Settings(aSettings));
188     }
189     else
190     {
191         message = instance.Get<Ip6::Ip6>().NewMessage(aData, aDataLength);
192     }
193 
194     return message;
195 }
196 
otIp6AddUnsecurePort(otInstance * aInstance,uint16_t aPort)197 otError otIp6AddUnsecurePort(otInstance *aInstance, uint16_t aPort)
198 {
199     Instance &instance = *static_cast<Instance *>(aInstance);
200 
201     return instance.Get<Ip6::Filter>().AddUnsecurePort(aPort);
202 }
203 
otIp6RemoveUnsecurePort(otInstance * aInstance,uint16_t aPort)204 otError otIp6RemoveUnsecurePort(otInstance *aInstance, uint16_t aPort)
205 {
206     Instance &instance = *static_cast<Instance *>(aInstance);
207 
208     return instance.Get<Ip6::Filter>().RemoveUnsecurePort(aPort);
209 }
210 
otIp6RemoveAllUnsecurePorts(otInstance * aInstance)211 void otIp6RemoveAllUnsecurePorts(otInstance *aInstance)
212 {
213     Instance &instance = *static_cast<Instance *>(aInstance);
214 
215     instance.Get<Ip6::Filter>().RemoveAllUnsecurePorts();
216 }
217 
otIp6GetUnsecurePorts(otInstance * aInstance,uint8_t * aNumEntries)218 const uint16_t *otIp6GetUnsecurePorts(otInstance *aInstance, uint8_t *aNumEntries)
219 {
220     Instance &instance = *static_cast<Instance *>(aInstance);
221 
222     return instance.Get<Ip6::Filter>().GetUnsecurePorts(*aNumEntries);
223 }
224 
otIp6IsAddressEqual(const otIp6Address * aFirst,const otIp6Address * aSecond)225 bool otIp6IsAddressEqual(const otIp6Address *aFirst, const otIp6Address *aSecond)
226 {
227     return *static_cast<const Ip6::Address *>(aFirst) == *static_cast<const Ip6::Address *>(aSecond);
228 }
229 
otIp6ArePrefixesEqual(const otIp6Prefix * aFirst,const otIp6Prefix * aSecond)230 bool otIp6ArePrefixesEqual(const otIp6Prefix *aFirst, const otIp6Prefix *aSecond)
231 {
232     return *static_cast<const Ip6::Prefix *>(aFirst) == *static_cast<const Ip6::Prefix *>(aSecond);
233 }
234 
otIp6AddressFromString(const char * aString,otIp6Address * aAddress)235 otError otIp6AddressFromString(const char *aString, otIp6Address *aAddress)
236 {
237     return static_cast<Ip6::Address *>(aAddress)->FromString(aString);
238 }
239 
otIp6AddressToString(const otIp6Address * aAddress,char * aBuffer,uint16_t aSize)240 void otIp6AddressToString(const otIp6Address *aAddress, char *aBuffer, uint16_t aSize)
241 {
242     static_cast<const Ip6::Address *>(aAddress)->ToString(aBuffer, aSize);
243 }
244 
otIp6SockAddrToString(const otSockAddr * aSockAddr,char * aBuffer,uint16_t aSize)245 void otIp6SockAddrToString(const otSockAddr *aSockAddr, char *aBuffer, uint16_t aSize)
246 {
247     static_cast<const Ip6::SockAddr *>(aSockAddr)->ToString(aBuffer, aSize);
248 }
249 
otIp6PrefixToString(const otIp6Prefix * aPrefix,char * aBuffer,uint16_t aSize)250 void otIp6PrefixToString(const otIp6Prefix *aPrefix, char *aBuffer, uint16_t aSize)
251 {
252     static_cast<const Ip6::Prefix *>(aPrefix)->ToString(aBuffer, aSize);
253 }
254 
otIp6PrefixMatch(const otIp6Address * aFirst,const otIp6Address * aSecond)255 uint8_t otIp6PrefixMatch(const otIp6Address *aFirst, const otIp6Address *aSecond)
256 {
257     OT_ASSERT(aFirst != nullptr && aSecond != nullptr);
258 
259     return static_cast<const Ip6::Address *>(aFirst)->PrefixMatch(*static_cast<const Ip6::Address *>(aSecond));
260 }
261 
otIp6IsAddressUnspecified(const otIp6Address * aAddress)262 bool otIp6IsAddressUnspecified(const otIp6Address *aAddress)
263 {
264     return static_cast<const Ip6::Address *>(aAddress)->IsUnspecified();
265 }
266 
otIp6SelectSourceAddress(otInstance * aInstance,otMessageInfo * aMessageInfo)267 otError otIp6SelectSourceAddress(otInstance *aInstance, otMessageInfo *aMessageInfo)
268 {
269     Error                             error    = kErrorNone;
270     Instance &                        instance = *static_cast<Instance *>(aInstance);
271     const Ip6::Netif::UnicastAddress *netifAddr;
272 
273     netifAddr = instance.Get<Ip6::Ip6>().SelectSourceAddress(*static_cast<Ip6::MessageInfo *>(aMessageInfo));
274     VerifyOrExit(netifAddr != nullptr, error = kErrorNotFound);
275     aMessageInfo->mSockAddr = netifAddr->GetAddress();
276 
277 exit:
278     return error;
279 }
280 
281 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE && OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
otIp6RegisterMulticastListeners(otInstance * aInstance,const otIp6Address * aAddresses,uint8_t aAddressNum,const uint32_t * aTimeout,otIp6RegisterMulticastListenersCallback aCallback,void * aContext)282 otError otIp6RegisterMulticastListeners(otInstance *                            aInstance,
283                                         const otIp6Address *                    aAddresses,
284                                         uint8_t                                 aAddressNum,
285                                         const uint32_t *                        aTimeout,
286                                         otIp6RegisterMulticastListenersCallback aCallback,
287                                         void *                                  aContext)
288 {
289     Instance &instance = *static_cast<Instance *>(aInstance);
290 
291     return instance.Get<MlrManager>().RegisterMulticastListeners(aAddresses, aAddressNum, aTimeout, aCallback,
292                                                                  aContext);
293 }
294 #endif
295 
296 #if OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
297 
otIp6IsSlaacEnabled(otInstance * aInstance)298 bool otIp6IsSlaacEnabled(otInstance *aInstance)
299 {
300     return static_cast<Instance *>(aInstance)->Get<Utils::Slaac>().IsEnabled();
301 }
302 
otIp6SetSlaacEnabled(otInstance * aInstance,bool aEnabled)303 void otIp6SetSlaacEnabled(otInstance *aInstance, bool aEnabled)
304 {
305     Instance &instance = *static_cast<Instance *>(aInstance);
306 
307     if (aEnabled)
308     {
309         instance.Get<Utils::Slaac>().Enable();
310     }
311     else
312     {
313         instance.Get<Utils::Slaac>().Disable();
314     }
315 }
316 
otIp6SetSlaacPrefixFilter(otInstance * aInstance,otIp6SlaacPrefixFilter aFilter)317 void otIp6SetSlaacPrefixFilter(otInstance *aInstance, otIp6SlaacPrefixFilter aFilter)
318 {
319     Instance &instance = *static_cast<Instance *>(aInstance);
320 
321     instance.Get<Utils::Slaac>().SetFilter(aFilter);
322 }
323 
324 #endif // OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
325 
326 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
327 
otIp6SetMeshLocalIid(otInstance * aInstance,const otIp6InterfaceIdentifier * aIid)328 otError otIp6SetMeshLocalIid(otInstance *aInstance, const otIp6InterfaceIdentifier *aIid)
329 {
330     Instance &instance = *static_cast<Instance *>(aInstance);
331 
332     return instance.Get<Mle::MleRouter>().SetMeshLocalIid(static_cast<const Ip6::InterfaceIdentifier &>(*aIid));
333 }
334 
335 #endif
336 
otIp6ProtoToString(uint8_t aIpProto)337 const char *otIp6ProtoToString(uint8_t aIpProto)
338 {
339     return Ip6::Ip6::IpProtoToString(aIpProto);
340 }
341