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/as_core_type.hpp"
39 #include "common/locator_getters.hpp"
40 #include "net/ip4_types.hpp"
41 #include "net/ip6_headers.hpp"
42 #include "thread/network_data_leader.hpp"
43 #include "utils/slaac_address.hpp"
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 = AsCoreType(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) { return AsCoreType(aInstance).Get<ThreadNetif>().IsUp(); }
72 
otIp6GetUnicastAddresses(otInstance * aInstance)73 const otNetifAddress *otIp6GetUnicastAddresses(otInstance *aInstance)
74 {
75     return AsCoreType(aInstance).Get<ThreadNetif>().GetUnicastAddresses().GetHead();
76 }
77 
otIp6AddUnicastAddress(otInstance * aInstance,const otNetifAddress * aAddress)78 otError otIp6AddUnicastAddress(otInstance *aInstance, const otNetifAddress *aAddress)
79 {
80     return AsCoreType(aInstance).Get<ThreadNetif>().AddExternalUnicastAddress(AsCoreType(aAddress));
81 }
82 
otIp6RemoveUnicastAddress(otInstance * aInstance,const otIp6Address * aAddress)83 otError otIp6RemoveUnicastAddress(otInstance *aInstance, const otIp6Address *aAddress)
84 {
85     return AsCoreType(aInstance).Get<ThreadNetif>().RemoveExternalUnicastAddress(AsCoreType(aAddress));
86 }
87 
otIp6GetMulticastAddresses(otInstance * aInstance)88 const otNetifMulticastAddress *otIp6GetMulticastAddresses(otInstance *aInstance)
89 {
90     return AsCoreType(aInstance).Get<ThreadNetif>().GetMulticastAddresses().GetHead();
91 }
92 
otIp6SubscribeMulticastAddress(otInstance * aInstance,const otIp6Address * aAddress)93 otError otIp6SubscribeMulticastAddress(otInstance *aInstance, const otIp6Address *aAddress)
94 {
95     return AsCoreType(aInstance).Get<ThreadNetif>().SubscribeExternalMulticast(AsCoreType(aAddress));
96 }
97 
otIp6UnsubscribeMulticastAddress(otInstance * aInstance,const otIp6Address * aAddress)98 otError otIp6UnsubscribeMulticastAddress(otInstance *aInstance, const otIp6Address *aAddress)
99 {
100     return AsCoreType(aInstance).Get<ThreadNetif>().UnsubscribeExternalMulticast(AsCoreType(aAddress));
101 }
102 
otIp6IsMulticastPromiscuousEnabled(otInstance * aInstance)103 bool otIp6IsMulticastPromiscuousEnabled(otInstance *aInstance)
104 {
105     return AsCoreType(aInstance).Get<ThreadNetif>().IsMulticastPromiscuousEnabled();
106 }
107 
otIp6SetMulticastPromiscuousEnabled(otInstance * aInstance,bool aEnabled)108 void otIp6SetMulticastPromiscuousEnabled(otInstance *aInstance, bool aEnabled)
109 {
110     AsCoreType(aInstance).Get<ThreadNetif>().SetMulticastPromiscuous(aEnabled);
111 }
112 
otIp6SetReceiveCallback(otInstance * aInstance,otIp6ReceiveCallback aCallback,void * aCallbackContext)113 void otIp6SetReceiveCallback(otInstance *aInstance, otIp6ReceiveCallback aCallback, void *aCallbackContext)
114 {
115     AsCoreType(aInstance).Get<Ip6::Ip6>().SetReceiveDatagramCallback(aCallback, aCallbackContext);
116 }
117 
otIp6SetAddressCallback(otInstance * aInstance,otIp6AddressCallback aCallback,void * aCallbackContext)118 void otIp6SetAddressCallback(otInstance *aInstance, otIp6AddressCallback aCallback, void *aCallbackContext)
119 {
120     AsCoreType(aInstance).Get<ThreadNetif>().SetAddressCallback(aCallback, aCallbackContext);
121 }
122 
otIp6IsReceiveFilterEnabled(otInstance * aInstance)123 bool otIp6IsReceiveFilterEnabled(otInstance *aInstance)
124 {
125     return AsCoreType(aInstance).Get<Ip6::Ip6>().IsReceiveIp6FilterEnabled();
126 }
127 
otIp6SetReceiveFilterEnabled(otInstance * aInstance,bool aEnabled)128 void otIp6SetReceiveFilterEnabled(otInstance *aInstance, bool aEnabled)
129 {
130     AsCoreType(aInstance).Get<Ip6::Ip6>().SetReceiveIp6FilterEnabled(aEnabled);
131 }
132 
otIp6Send(otInstance * aInstance,otMessage * aMessage)133 otError otIp6Send(otInstance *aInstance, otMessage *aMessage)
134 {
135     return AsCoreType(aInstance).Get<Ip6::Ip6>().SendRaw(AsCoreType(aMessage),
136                                                          OPENTHREAD_CONFIG_IP6_ALLOW_LOOP_BACK_HOST_DATAGRAMS);
137 }
138 
otIp6NewMessage(otInstance * aInstance,const otMessageSettings * aSettings)139 otMessage *otIp6NewMessage(otInstance *aInstance, const otMessageSettings *aSettings)
140 {
141     return AsCoreType(aInstance).Get<Ip6::Ip6>().NewMessage(0, Message::Settings::From(aSettings));
142 }
143 
otIp6NewMessageFromBuffer(otInstance * aInstance,const uint8_t * aData,uint16_t aDataLength,const otMessageSettings * aSettings)144 otMessage *otIp6NewMessageFromBuffer(otInstance              *aInstance,
145                                      const uint8_t           *aData,
146                                      uint16_t                 aDataLength,
147                                      const otMessageSettings *aSettings)
148 {
149     return AsCoreType(aInstance).Get<Ip6::Ip6>().NewMessageFromData(aData, aDataLength,
150                                                                     Message::Settings::From(aSettings));
151 }
152 
otIp6AddUnsecurePort(otInstance * aInstance,uint16_t aPort)153 otError otIp6AddUnsecurePort(otInstance *aInstance, uint16_t aPort)
154 {
155     return AsCoreType(aInstance).Get<Ip6::Filter>().AddUnsecurePort(aPort);
156 }
157 
otIp6RemoveUnsecurePort(otInstance * aInstance,uint16_t aPort)158 otError otIp6RemoveUnsecurePort(otInstance *aInstance, uint16_t aPort)
159 {
160     return AsCoreType(aInstance).Get<Ip6::Filter>().RemoveUnsecurePort(aPort);
161 }
162 
otIp6RemoveAllUnsecurePorts(otInstance * aInstance)163 void otIp6RemoveAllUnsecurePorts(otInstance *aInstance)
164 {
165     AsCoreType(aInstance).Get<Ip6::Filter>().RemoveAllUnsecurePorts();
166 }
167 
otIp6GetUnsecurePorts(otInstance * aInstance,uint8_t * aNumEntries)168 const uint16_t *otIp6GetUnsecurePorts(otInstance *aInstance, uint8_t *aNumEntries)
169 {
170     AssertPointerIsNotNull(aNumEntries);
171 
172     return AsCoreType(aInstance).Get<Ip6::Filter>().GetUnsecurePorts(*aNumEntries);
173 }
174 
otIp6IsAddressEqual(const otIp6Address * aFirst,const otIp6Address * aSecond)175 bool otIp6IsAddressEqual(const otIp6Address *aFirst, const otIp6Address *aSecond)
176 {
177     return AsCoreType(aFirst) == AsCoreType(aSecond);
178 }
179 
otIp6ArePrefixesEqual(const otIp6Prefix * aFirst,const otIp6Prefix * aSecond)180 bool otIp6ArePrefixesEqual(const otIp6Prefix *aFirst, const otIp6Prefix *aSecond)
181 {
182     return AsCoreType(aFirst) == AsCoreType(aSecond);
183 }
184 
otIp6AddressFromString(const char * aString,otIp6Address * aAddress)185 otError otIp6AddressFromString(const char *aString, otIp6Address *aAddress)
186 {
187     return AsCoreType(aAddress).FromString(aString);
188 }
189 
otIp6PrefixFromString(const char * aString,otIp6Prefix * aPrefix)190 otError otIp6PrefixFromString(const char *aString, otIp6Prefix *aPrefix)
191 {
192     return AsCoreType(aPrefix).FromString(aString);
193 }
194 
otIp6AddressToString(const otIp6Address * aAddress,char * aBuffer,uint16_t aSize)195 void otIp6AddressToString(const otIp6Address *aAddress, char *aBuffer, uint16_t aSize)
196 {
197     AssertPointerIsNotNull(aBuffer);
198 
199     AsCoreType(aAddress).ToString(aBuffer, aSize);
200 }
201 
otIp6SockAddrToString(const otSockAddr * aSockAddr,char * aBuffer,uint16_t aSize)202 void otIp6SockAddrToString(const otSockAddr *aSockAddr, char *aBuffer, uint16_t aSize)
203 {
204     AssertPointerIsNotNull(aBuffer);
205 
206     AsCoreType(aSockAddr).ToString(aBuffer, aSize);
207 }
208 
otIp6PrefixToString(const otIp6Prefix * aPrefix,char * aBuffer,uint16_t aSize)209 void otIp6PrefixToString(const otIp6Prefix *aPrefix, char *aBuffer, uint16_t aSize)
210 {
211     AssertPointerIsNotNull(aBuffer);
212 
213     AsCoreType(aPrefix).ToString(aBuffer, aSize);
214 }
215 
otIp6PrefixMatch(const otIp6Address * aFirst,const otIp6Address * aSecond)216 uint8_t otIp6PrefixMatch(const otIp6Address *aFirst, const otIp6Address *aSecond)
217 {
218     return AsCoreType(aFirst).PrefixMatch(AsCoreType(aSecond));
219 }
220 
otIp6GetPrefix(const otIp6Address * aAddress,uint8_t aLength,otIp6Prefix * aPrefix)221 void otIp6GetPrefix(const otIp6Address *aAddress, uint8_t aLength, otIp6Prefix *aPrefix)
222 {
223     AsCoreType(aAddress).GetPrefix(aLength, AsCoreType(aPrefix));
224 }
225 
otIp6IsAddressUnspecified(const otIp6Address * aAddress)226 bool otIp6IsAddressUnspecified(const otIp6Address *aAddress) { return AsCoreType(aAddress).IsUnspecified(); }
227 
otIp6SelectSourceAddress(otInstance * aInstance,otMessageInfo * aMessageInfo)228 otError otIp6SelectSourceAddress(otInstance *aInstance, otMessageInfo *aMessageInfo)
229 {
230     return AsCoreType(aInstance).Get<Ip6::Ip6>().SelectSourceAddress(AsCoreType(aMessageInfo));
231 }
232 
233 #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)234 otError otIp6RegisterMulticastListeners(otInstance                             *aInstance,
235                                         const otIp6Address                     *aAddresses,
236                                         uint8_t                                 aAddressNum,
237                                         const uint32_t                         *aTimeout,
238                                         otIp6RegisterMulticastListenersCallback aCallback,
239                                         void                                   *aContext)
240 {
241     return AsCoreType(aInstance).Get<MlrManager>().RegisterMulticastListeners(aAddresses, aAddressNum, aTimeout,
242                                                                               aCallback, aContext);
243 }
244 #endif
245 
246 #if OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
247 
otIp6IsSlaacEnabled(otInstance * aInstance)248 bool otIp6IsSlaacEnabled(otInstance *aInstance) { return AsCoreType(aInstance).Get<Utils::Slaac>().IsEnabled(); }
249 
otIp6SetSlaacEnabled(otInstance * aInstance,bool aEnabled)250 void otIp6SetSlaacEnabled(otInstance *aInstance, bool aEnabled)
251 {
252     Instance &instance = AsCoreType(aInstance);
253 
254     if (aEnabled)
255     {
256         instance.Get<Utils::Slaac>().Enable();
257     }
258     else
259     {
260         instance.Get<Utils::Slaac>().Disable();
261     }
262 }
263 
otIp6SetSlaacPrefixFilter(otInstance * aInstance,otIp6SlaacPrefixFilter aFilter)264 void otIp6SetSlaacPrefixFilter(otInstance *aInstance, otIp6SlaacPrefixFilter aFilter)
265 {
266     AsCoreType(aInstance).Get<Utils::Slaac>().SetFilter(aFilter);
267 }
268 
269 #endif // OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
270 
271 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
272 
otIp6SetMeshLocalIid(otInstance * aInstance,const otIp6InterfaceIdentifier * aIid)273 otError otIp6SetMeshLocalIid(otInstance *aInstance, const otIp6InterfaceIdentifier *aIid)
274 {
275     return AsCoreType(aInstance).Get<Mle::MleRouter>().SetMeshLocalIid(AsCoreType(aIid));
276 }
277 
278 #endif
279 
otIp6ProtoToString(uint8_t aIpProto)280 const char *otIp6ProtoToString(uint8_t aIpProto) { return Ip6::Ip6::IpProtoToString(aIpProto); }
281 
282 #if OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE
otIp6GetBorderRoutingCounters(otInstance * aInstance)283 const otBorderRoutingCounters *otIp6GetBorderRoutingCounters(otInstance *aInstance)
284 {
285     return &AsCoreType(aInstance).Get<Ip6::Ip6>().GetBorderRoutingCounters();
286 }
287 
otIp6ResetBorderRoutingCounters(otInstance * aInstance)288 void otIp6ResetBorderRoutingCounters(otInstance *aInstance)
289 {
290     AsCoreType(aInstance).Get<Ip6::Ip6>().ResetBorderRoutingCounters();
291 }
292 #endif
293