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