1 /*
2 * Copyright (c) 2016-21, 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 Thread Network Data related types and constants.
32 */
33
34 #include "network_data_types.hpp"
35
36 #include "common/instance.hpp"
37 #include "thread/network_data_tlvs.hpp"
38
39 namespace ot {
40 namespace NetworkData {
41
42 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
43
IsPrefixValid(Instance & aInstance,const Ip6::Prefix & aPrefix)44 static bool IsPrefixValid(Instance &aInstance, const Ip6::Prefix &aPrefix)
45 {
46 // Check that prefix length is within the valid range and the prefix
47 // does not overlap with the mesh-local prefix.
48
49 return aPrefix.IsValid() && !aPrefix.ContainsPrefix(aInstance.Get<Mle::Mle>().GetMeshLocalPrefix());
50 }
51
IsValid(Instance & aInstance) const52 bool OnMeshPrefixConfig::IsValid(Instance &aInstance) const
53 {
54 bool isValid = false;
55
56 if (mDhcp && mSlaac)
57 {
58 // A valid prefix MUST NOT allow both DHCPv6 and SLAAC for
59 // address configuration.
60 ExitNow();
61 }
62
63 if (mSlaac)
64 {
65 // An IPv6 address prefix used for stateless auto-configuration
66 // [RFC4862] of an IEEE 802.15.4 interface MUST have a length of
67 // 64 bits.
68 VerifyOrExit(GetPrefix().GetLength() == Ip6::NetworkPrefix::kLength);
69 }
70
71 VerifyOrExit(IsRoutePreferenceValid(mPreference));
72 VerifyOrExit(IsPrefixValid(aInstance, GetPrefix()));
73 VerifyOrExit(GetPrefix().GetLength() > 0);
74
75 isValid = true;
76
77 exit:
78 return isValid;
79 }
80
ConvertToTlvFlags(void) const81 uint16_t OnMeshPrefixConfig::ConvertToTlvFlags(void) const
82 {
83 uint16_t flags = 0;
84
85 if (mPreferred)
86 {
87 flags |= BorderRouterEntry::kPreferredFlag;
88 }
89
90 if (mSlaac)
91 {
92 flags |= BorderRouterEntry::kSlaacFlag;
93 }
94
95 if (mDhcp)
96 {
97 flags |= BorderRouterEntry::kDhcpFlag;
98 }
99
100 if (mConfigure)
101 {
102 flags |= BorderRouterEntry::kConfigureFlag;
103 }
104
105 if (mDefaultRoute)
106 {
107 flags |= BorderRouterEntry::kDefaultRouteFlag;
108 }
109
110 if (mOnMesh)
111 {
112 flags |= BorderRouterEntry::kOnMeshFlag;
113 }
114
115 if (mNdDns)
116 {
117 flags |= BorderRouterEntry::kNdDnsFlag;
118 }
119
120 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
121 if (mDp)
122 {
123 flags |= BorderRouterEntry::kDpFlag;
124 }
125 #endif
126
127 flags |= (static_cast<uint16_t>(RoutePreferenceToValue(mPreference)) << BorderRouterEntry::kPreferenceOffset);
128
129 return flags;
130 }
131
132 #endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
133
SetFrom(const PrefixTlv & aPrefixTlv,const BorderRouterTlv & aBorderRouterTlv,const BorderRouterEntry & aBorderRouterEntry)134 void OnMeshPrefixConfig::SetFrom(const PrefixTlv & aPrefixTlv,
135 const BorderRouterTlv & aBorderRouterTlv,
136 const BorderRouterEntry &aBorderRouterEntry)
137 {
138 Clear();
139
140 aPrefixTlv.CopyPrefixTo(GetPrefix());
141 SetFromTlvFlags(aBorderRouterEntry.GetFlags());
142 mRloc16 = aBorderRouterEntry.GetRloc();
143 mStable = aBorderRouterTlv.IsStable();
144 }
145
SetFromTlvFlags(uint16_t aFlags)146 void OnMeshPrefixConfig::SetFromTlvFlags(uint16_t aFlags)
147 {
148 mPreferred = ((aFlags & BorderRouterEntry::kPreferredFlag) != 0);
149 mSlaac = ((aFlags & BorderRouterEntry::kSlaacFlag) != 0);
150 mDhcp = ((aFlags & BorderRouterEntry::kDhcpFlag) != 0);
151 mConfigure = ((aFlags & BorderRouterEntry::kConfigureFlag) != 0);
152 mDefaultRoute = ((aFlags & BorderRouterEntry::kDefaultRouteFlag) != 0);
153 mOnMesh = ((aFlags & BorderRouterEntry::kOnMeshFlag) != 0);
154 mNdDns = ((aFlags & BorderRouterEntry::kNdDnsFlag) != 0);
155 mDp = ((aFlags & BorderRouterEntry::kDpFlag) != 0);
156 mPreference = RoutePreferenceFromValue(static_cast<uint8_t>(aFlags >> BorderRouterEntry::kPreferenceOffset));
157 }
158
159 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
IsValid(Instance & aInstance) const160 bool ExternalRouteConfig::IsValid(Instance &aInstance) const
161 {
162 bool isValid = false;
163
164 if (mNat64)
165 {
166 VerifyOrExit(GetPrefix().IsValidNat64());
167 }
168
169 VerifyOrExit(IsRoutePreferenceValid(mPreference));
170 VerifyOrExit(IsPrefixValid(aInstance, GetPrefix()));
171
172 isValid = true;
173
174 exit:
175 return isValid;
176 }
177
ConvertToTlvFlags(void) const178 uint8_t ExternalRouteConfig::ConvertToTlvFlags(void) const
179 {
180 uint8_t flags = 0;
181
182 if (mNat64)
183 {
184 flags |= HasRouteEntry::kNat64Flag;
185 }
186
187 flags |= (RoutePreferenceToValue(mPreference) << HasRouteEntry::kPreferenceOffset);
188
189 return flags;
190 }
191
192 #endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
193
SetFrom(Instance & aInstance,const PrefixTlv & aPrefixTlv,const HasRouteTlv & aHasRouteTlv,const HasRouteEntry & aHasRouteEntry)194 void ExternalRouteConfig::SetFrom(Instance & aInstance,
195 const PrefixTlv & aPrefixTlv,
196 const HasRouteTlv & aHasRouteTlv,
197 const HasRouteEntry &aHasRouteEntry)
198 {
199 Clear();
200
201 aPrefixTlv.CopyPrefixTo(GetPrefix());
202 SetFromTlvFlags(aHasRouteEntry.GetFlags());
203 mStable = aHasRouteTlv.IsStable();
204 mRloc16 = aHasRouteEntry.GetRloc();
205 mNextHopIsThisDevice = (aHasRouteEntry.GetRloc() == aInstance.Get<Mle::MleRouter>().GetRloc16());
206 }
207
SetFromTlvFlags(uint8_t aFlags)208 void ExternalRouteConfig::SetFromTlvFlags(uint8_t aFlags)
209 {
210 mNat64 = ((aFlags & HasRouteEntry::kNat64Flag) != 0);
211 mPreference = RoutePreferenceFromValue(aFlags >> HasRouteEntry::kPreferenceOffset);
212 }
213
operator ==(const ServerConfig & aOther) const214 bool ServiceConfig::ServerConfig::operator==(const ServerConfig &aOther) const
215 {
216 return (mStable == aOther.mStable) && (mServerDataLength == aOther.mServerDataLength) &&
217 (memcmp(mServerData, aOther.mServerData, mServerDataLength) == 0);
218 }
219
SetFrom(const ServerTlv & aServerTlv)220 void ServiceConfig::ServerConfig::SetFrom(const ServerTlv &aServerTlv)
221 {
222 ServerData serverData;
223
224 aServerTlv.GetServerData(serverData);
225 mStable = aServerTlv.IsStable();
226 mRloc16 = aServerTlv.GetServer16();
227 mServerDataLength = serverData.GetLength();
228 serverData.CopyBytesTo(mServerData);
229 }
230
operator ==(const ServiceConfig & aOther) const231 bool ServiceConfig::operator==(const ServiceConfig &aOther) const
232 {
233 return (mEnterpriseNumber == aOther.mEnterpriseNumber) && (mServiceDataLength == aOther.mServiceDataLength) &&
234 (memcmp(mServiceData, aOther.mServiceData, mServiceDataLength) == 0) &&
235 (GetServerConfig() == aOther.GetServerConfig());
236 }
237
SetFrom(const ServiceTlv & aServiceTlv,const ServerTlv & aServerTlv)238 void ServiceConfig::SetFrom(const ServiceTlv &aServiceTlv, const ServerTlv &aServerTlv)
239 {
240 ServiceData serviceData;
241
242 Clear();
243
244 aServiceTlv.GetServiceData(serviceData);
245 mServiceId = aServiceTlv.GetServiceId();
246 mEnterpriseNumber = aServiceTlv.GetEnterpriseNumber();
247 mServiceDataLength = serviceData.GetLength();
248 serviceData.CopyBytesTo(mServiceData);
249 GetServerConfig().SetFrom(aServerTlv);
250 }
251
252 } // namespace NetworkData
253 } // namespace ot
254