blob: 628f780a744f3b0378b8ac40de98f3312f3fcc48 [file] [log] [blame]
/*
* Copyright (c) 2016-21, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file implements Thread Network Data related types and constants.
*/
#include "network_data_types.hpp"
#include "common/instance.hpp"
#include "thread/network_data_tlvs.hpp"
namespace ot {
namespace NetworkData {
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
static bool IsPrefixValid(Instance &aInstance, const Ip6::Prefix &aPrefix)
{
// Check that prefix length is within the valid range and the prefix
// does not overlap with the mesh-local prefix.
return aPrefix.IsValid() && !aPrefix.ContainsPrefix(aInstance.Get<Mle::Mle>().GetMeshLocalPrefix());
}
bool OnMeshPrefixConfig::IsValid(Instance &aInstance) const
{
bool isValid = false;
if (mDhcp && mSlaac)
{
// A valid prefix MUST NOT allow both DHCPv6 and SLAAC for
// address configuration.
ExitNow();
}
if (mSlaac)
{
// An IPv6 address prefix used for stateless auto-configuration
// [RFC4862] of an IEEE 802.15.4 interface MUST have a length of
// 64 bits.
VerifyOrExit(GetPrefix().GetLength() == Ip6::NetworkPrefix::kLength);
}
VerifyOrExit(IsRoutePreferenceValid(mPreference));
VerifyOrExit(IsPrefixValid(aInstance, GetPrefix()));
VerifyOrExit(GetPrefix().GetLength() > 0);
isValid = true;
exit:
return isValid;
}
uint16_t OnMeshPrefixConfig::ConvertToTlvFlags(void) const
{
uint16_t flags = 0;
if (mPreferred)
{
flags |= BorderRouterEntry::kPreferredFlag;
}
if (mSlaac)
{
flags |= BorderRouterEntry::kSlaacFlag;
}
if (mDhcp)
{
flags |= BorderRouterEntry::kDhcpFlag;
}
if (mConfigure)
{
flags |= BorderRouterEntry::kConfigureFlag;
}
if (mDefaultRoute)
{
flags |= BorderRouterEntry::kDefaultRouteFlag;
}
if (mOnMesh)
{
flags |= BorderRouterEntry::kOnMeshFlag;
}
if (mNdDns)
{
flags |= BorderRouterEntry::kNdDnsFlag;
}
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
if (mDp)
{
flags |= BorderRouterEntry::kDpFlag;
}
#endif
flags |= (static_cast<uint16_t>(RoutePreferenceToValue(mPreference)) << BorderRouterEntry::kPreferenceOffset);
return flags;
}
#endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
void OnMeshPrefixConfig::SetFrom(const PrefixTlv & aPrefixTlv,
const BorderRouterTlv & aBorderRouterTlv,
const BorderRouterEntry &aBorderRouterEntry)
{
Clear();
aPrefixTlv.CopyPrefixTo(GetPrefix());
SetFromTlvFlags(aBorderRouterEntry.GetFlags());
mRloc16 = aBorderRouterEntry.GetRloc();
mStable = aBorderRouterTlv.IsStable();
}
void OnMeshPrefixConfig::SetFromTlvFlags(uint16_t aFlags)
{
mPreferred = ((aFlags & BorderRouterEntry::kPreferredFlag) != 0);
mSlaac = ((aFlags & BorderRouterEntry::kSlaacFlag) != 0);
mDhcp = ((aFlags & BorderRouterEntry::kDhcpFlag) != 0);
mConfigure = ((aFlags & BorderRouterEntry::kConfigureFlag) != 0);
mDefaultRoute = ((aFlags & BorderRouterEntry::kDefaultRouteFlag) != 0);
mOnMesh = ((aFlags & BorderRouterEntry::kOnMeshFlag) != 0);
mNdDns = ((aFlags & BorderRouterEntry::kNdDnsFlag) != 0);
mDp = ((aFlags & BorderRouterEntry::kDpFlag) != 0);
mPreference = RoutePreferenceFromValue(static_cast<uint8_t>(aFlags >> BorderRouterEntry::kPreferenceOffset));
}
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
bool ExternalRouteConfig::IsValid(Instance &aInstance) const
{
bool isValid = false;
if (mNat64)
{
VerifyOrExit(GetPrefix().IsValidNat64());
}
VerifyOrExit(IsRoutePreferenceValid(mPreference));
VerifyOrExit(IsPrefixValid(aInstance, GetPrefix()));
isValid = true;
exit:
return isValid;
}
uint8_t ExternalRouteConfig::ConvertToTlvFlags(void) const
{
uint8_t flags = 0;
if (mNat64)
{
flags |= HasRouteEntry::kNat64Flag;
}
flags |= (RoutePreferenceToValue(mPreference) << HasRouteEntry::kPreferenceOffset);
return flags;
}
#endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
void ExternalRouteConfig::SetFrom(Instance & aInstance,
const PrefixTlv & aPrefixTlv,
const HasRouteTlv & aHasRouteTlv,
const HasRouteEntry &aHasRouteEntry)
{
Clear();
aPrefixTlv.CopyPrefixTo(GetPrefix());
SetFromTlvFlags(aHasRouteEntry.GetFlags());
mStable = aHasRouteTlv.IsStable();
mRloc16 = aHasRouteEntry.GetRloc();
mNextHopIsThisDevice = (aHasRouteEntry.GetRloc() == aInstance.Get<Mle::MleRouter>().GetRloc16());
}
void ExternalRouteConfig::SetFromTlvFlags(uint8_t aFlags)
{
mNat64 = ((aFlags & HasRouteEntry::kNat64Flag) != 0);
mPreference = RoutePreferenceFromValue(aFlags >> HasRouteEntry::kPreferenceOffset);
}
bool ServiceConfig::ServerConfig::operator==(const ServerConfig &aOther) const
{
return (mStable == aOther.mStable) && (mServerDataLength == aOther.mServerDataLength) &&
(memcmp(mServerData, aOther.mServerData, mServerDataLength) == 0);
}
void ServiceConfig::ServerConfig::SetFrom(const ServerTlv &aServerTlv)
{
ServerData serverData;
aServerTlv.GetServerData(serverData);
mStable = aServerTlv.IsStable();
mRloc16 = aServerTlv.GetServer16();
mServerDataLength = serverData.GetLength();
serverData.CopyBytesTo(mServerData);
}
bool ServiceConfig::operator==(const ServiceConfig &aOther) const
{
return (mEnterpriseNumber == aOther.mEnterpriseNumber) && (mServiceDataLength == aOther.mServiceDataLength) &&
(memcmp(mServiceData, aOther.mServiceData, mServiceDataLength) == 0) &&
(GetServerConfig() == aOther.GetServerConfig());
}
void ServiceConfig::SetFrom(const ServiceTlv &aServiceTlv, const ServerTlv &aServerTlv)
{
ServiceData serviceData;
Clear();
aServiceTlv.GetServiceData(serviceData);
mServiceId = aServiceTlv.GetServiceId();
mEnterpriseNumber = aServiceTlv.GetEnterpriseNumber();
mServiceDataLength = serviceData.GetLength();
serviceData.CopyBytesTo(mServiceData);
GetServerConfig().SetFrom(aServerTlv);
}
} // namespace NetworkData
} // namespace ot