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