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