1022 lines
35 KiB
C++
1022 lines
35 KiB
C++
/*
|
||
* Copyright (c) 2016, 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 includes definitions for IPv6 addresses.
|
||
*/
|
||
|
||
#ifndef IP6_ADDRESS_HPP_
|
||
#define IP6_ADDRESS_HPP_
|
||
|
||
#include "openthread-core-config.h"
|
||
|
||
#include <stdint.h>
|
||
|
||
#include <openthread/ip6.h>
|
||
|
||
#include "common/as_core_type.hpp"
|
||
#include "common/clearable.hpp"
|
||
#include "common/encoding.hpp"
|
||
#include "common/equatable.hpp"
|
||
#include "common/string.hpp"
|
||
#include "mac/mac_types.hpp"
|
||
#include "net/ip4_address.hpp"
|
||
|
||
using ot::Encoding::BigEndian::HostSwap16;
|
||
|
||
namespace ot {
|
||
namespace Ip6 {
|
||
|
||
/**
|
||
* @addtogroup core-ip6-ip6
|
||
*
|
||
* @{
|
||
*
|
||
*/
|
||
|
||
/**
|
||
* This class represents the Network Prefix of an IPv6 address (most significant 64 bits of the address).
|
||
*
|
||
*/
|
||
OT_TOOL_PACKED_BEGIN
|
||
class NetworkPrefix : public otIp6NetworkPrefix, public Equatable<NetworkPrefix>, public Clearable<NetworkPrefix>
|
||
{
|
||
public:
|
||
static constexpr uint8_t kSize = OT_IP6_PREFIX_SIZE; ///< Size in bytes.
|
||
static constexpr uint8_t kLength = OT_IP6_PREFIX_SIZE * CHAR_BIT; ///< Length of Network Prefix in bits.
|
||
|
||
/**
|
||
* This method generates and sets the Network Prefix to a crypto-secure random Unique Local Address (ULA) based
|
||
* on the pattern `fdxx:xxxx:xxxx:` (RFC 4193).
|
||
*
|
||
* @retval kErrorNone Successfully generated a random ULA Network Prefix
|
||
* @retval kErrorFailed Failed to generate random ULA Network Prefix.
|
||
*
|
||
*/
|
||
Error GenerateRandomUla(void);
|
||
|
||
} OT_TOOL_PACKED_END;
|
||
|
||
/**
|
||
* This class represents an IPv6 Prefix.
|
||
*
|
||
*/
|
||
OT_TOOL_PACKED_BEGIN
|
||
class Prefix : public otIp6Prefix, public Clearable<Prefix>, public Unequatable<Prefix>
|
||
{
|
||
public:
|
||
static constexpr uint8_t kMaxLength = OT_IP6_ADDRESS_SIZE * CHAR_BIT; ///< Max length of a prefix in bits.
|
||
static constexpr uint8_t kMaxSize = OT_IP6_ADDRESS_SIZE; ///< Max (byte) size of a prefix.
|
||
|
||
static constexpr uint16_t kInfoStringSize = OT_IP6_PREFIX_STRING_SIZE; ///< Info string size (`ToString()`).
|
||
|
||
/**
|
||
* This type defines the fixed-length `String` object returned from `ToString()`.
|
||
*
|
||
*/
|
||
typedef String<kInfoStringSize> InfoString;
|
||
|
||
/**
|
||
* This method gets the prefix as a pointer to a byte array.
|
||
*
|
||
* @returns A pointer to a byte array containing the Prefix.
|
||
*
|
||
*/
|
||
const uint8_t *GetBytes(void) const { return mPrefix.mFields.m8; }
|
||
|
||
/**
|
||
* This method gets the subnet ID of the prefix.
|
||
*
|
||
* @returns The 16-bit subnet ID.
|
||
*
|
||
*/
|
||
uint16_t GetSubnetId(void) const { return HostSwap16(mPrefix.mFields.m16[3]); }
|
||
|
||
/**
|
||
* This method gets the prefix length (in bits).
|
||
*
|
||
* @returns The prefix length (in bits).
|
||
*
|
||
*/
|
||
uint8_t GetLength(void) const { return mLength; }
|
||
|
||
/**
|
||
* This method returns the size (in bytes) of the prefix.
|
||
*
|
||
* @returns The size (in bytes) of the prefix array.
|
||
*
|
||
*/
|
||
uint8_t GetBytesSize(void) const { return SizeForLength(mLength); }
|
||
|
||
/**
|
||
* This method sets the prefix.
|
||
*
|
||
* @param[in] aPrefix A pointer to buffer containing the prefix bytes.
|
||
* @param[in] aLength The length or prefix in bits.
|
||
*
|
||
*/
|
||
void Set(const uint8_t *aPrefix, uint8_t aLength);
|
||
|
||
/**
|
||
* This method sets the prefix from a given Network Prefix.
|
||
*
|
||
* @param[in] aNetworkPrefix A Network Prefix.
|
||
*
|
||
*/
|
||
void Set(const NetworkPrefix &aNetworkPrefix) { Set(aNetworkPrefix.m8, NetworkPrefix::kLength); }
|
||
|
||
/**
|
||
* This method sets the subnet ID of the prefix.
|
||
*
|
||
* @param[in] aSubnetId A 16-bit subnet ID.
|
||
*
|
||
*/
|
||
void SetSubnetId(uint16_t aSubnetId) { mPrefix.mFields.m16[3] = HostSwap16(aSubnetId); }
|
||
|
||
/**
|
||
* This method set the prefix length.
|
||
*
|
||
* @param[in] aLength The new prefix length (in bits).
|
||
*
|
||
*/
|
||
void SetLength(uint8_t aLength) { mLength = aLength; }
|
||
|
||
/**
|
||
* This method indicates whether prefix length is valid (smaller or equal to max length).
|
||
*
|
||
* @retval TRUE The prefix length is valid.
|
||
* @retval FALSE The prefix length is not valid.
|
||
*
|
||
*/
|
||
bool IsValid(void) const { return (mLength <= kMaxLength); }
|
||
|
||
/**
|
||
* This method indicates whether the prefix is a Link-Local prefix.
|
||
*
|
||
* @retval TRUE The prefix is a Link-Local prefix.
|
||
* @retval FALSE The prefix is not a Link-Local prefix.
|
||
*
|
||
*/
|
||
bool IsLinkLocal(void) const
|
||
{
|
||
return mLength >= 10 && mPrefix.mFields.m8[0] == 0xfe && (mPrefix.mFields.m8[1] & 0xc0) == 0x80;
|
||
}
|
||
|
||
/**
|
||
* This method indicates whether the prefix is a Multicast prefix.
|
||
*
|
||
* @retval TRUE The prefix is a Multicast prefix.
|
||
* @retval FALSE The prefix is not a Multicast prefix.
|
||
*
|
||
*/
|
||
bool IsMulticast(void) const { return mLength >= 8 && mPrefix.mFields.m8[0] == 0xff; }
|
||
|
||
/**
|
||
* This method indicates whether the prefix is a Unique-Local prefix.
|
||
*
|
||
* @retval TRUE The prefix is a Unique-Local prefix.
|
||
* @retval FALSE The prefix is not a Unique-Local prefix.
|
||
*
|
||
*/
|
||
bool IsUniqueLocal(void) const { return mLength >= 7 && (mPrefix.mFields.m8[0] & 0xfe) == 0xfc; }
|
||
|
||
/**
|
||
* This method indicates whether the prefix is equal to a given prefix.
|
||
*
|
||
* @param[in] aPrefixBytes A pointer to buffer containing the prefix bytes to compare with.
|
||
* @param[in] aPrefixLength The length of prefix (in bits) specified by @p aPrefixBytes.
|
||
*
|
||
* @retval TRUE If the prefix is equal to the specified prefix by @p aPrefixBytes and @p aPrefixLength.
|
||
* @retval FALSE If the prefix is not equal to the specified prefix by @p aPrefixBytes and @p aPrefixLength.
|
||
*
|
||
*/
|
||
bool IsEqual(const uint8_t *aPrefixBytes, uint8_t aPrefixLength) const;
|
||
|
||
/**
|
||
* This method indicates whether the prefix contains a sub-prefix.
|
||
*
|
||
* @param[in] aSubPrefix A sub-prefix.
|
||
*
|
||
* @retval TRUE The prefix contains the @p aSubPrefix
|
||
* @retval FALSE The prefix does not contains the @p aSubPrefix.
|
||
*
|
||
*/
|
||
bool ContainsPrefix(const Prefix &aSubPrefix) const
|
||
{
|
||
return (mLength >= aSubPrefix.mLength) &&
|
||
(MatchLength(GetBytes(), aSubPrefix.GetBytes(), aSubPrefix.GetBytesSize()) >= aSubPrefix.GetLength());
|
||
}
|
||
|
||
/**
|
||
* This method indicates whether the prefix contains a sub-prefix (given as a `NetworkPrefix`).
|
||
*
|
||
* @param[in] aSubPrefix A sub-prefix (as a `NetworkPrefix`).
|
||
*
|
||
* @retval TRUE The prefix contains the @p aSubPrefix
|
||
* @retval FALSE The prefix does not contains the @p aSubPrefix.
|
||
*
|
||
*/
|
||
bool ContainsPrefix(const NetworkPrefix &aSubPrefix) const
|
||
{
|
||
return (mLength >= NetworkPrefix::kLength) &&
|
||
(MatchLength(GetBytes(), aSubPrefix.m8, NetworkPrefix::kSize) >= NetworkPrefix::kLength);
|
||
}
|
||
|
||
/**
|
||
* This method overloads operator `==` to evaluate whether or not two prefixes are equal.
|
||
*
|
||
* @param[in] aOther The other prefix to compare with.
|
||
*
|
||
* @retval TRUE If the two prefixes are equal.
|
||
* @retval FALSE If the two prefixes are not equal.
|
||
*
|
||
*/
|
||
bool operator==(const Prefix &aOther) const
|
||
{
|
||
return (mLength == aOther.mLength) &&
|
||
(MatchLength(GetBytes(), aOther.GetBytes(), GetBytesSize()) >= GetLength());
|
||
}
|
||
|
||
/**
|
||
* This method overloads operator `<` to compare two prefixes.
|
||
*
|
||
* If the two prefixes have the same length N, then the bytes are compared directly (as two big-endian N-bit
|
||
* numbers). If the two prefix have different lengths, the shorter prefix is padded by `0` bit up to the longer
|
||
* prefix length N before the bytes are compared (as big-endian N-bit numbers). If all bytes are equal, the prefix
|
||
* with shorter length is considered smaller.
|
||
*
|
||
* @param[in] aOther The other prefix to compare against.
|
||
*
|
||
* @retval TRUE If the prefix is smaller than @p aOther.
|
||
* @retval FALSE If the prefix is not smaller than @p aOther.
|
||
*
|
||
*/
|
||
bool operator<(const Prefix &aOther) const;
|
||
|
||
/**
|
||
* This static method converts a prefix length (in bits) to size (number of bytes).
|
||
*
|
||
* @param[in] aLength A prefix length (in bits).
|
||
*
|
||
* @returns The size (in bytes) of the prefix.
|
||
*
|
||
*/
|
||
static uint8_t SizeForLength(uint8_t aLength) { return BitVectorBytes(aLength); }
|
||
|
||
/**
|
||
* This static method returns the number of IPv6 prefix bits that match.
|
||
*
|
||
* @param[in] aPrefixA A pointer to a byte array containing a first prefix.
|
||
* @param[in] aPrefixB A pointer to a byte array containing a second prefix.
|
||
* @param[in] aMaxSize Number of bytes of the two prefixes.
|
||
*
|
||
* @returns The number of prefix bits that match.
|
||
*
|
||
*/
|
||
static uint8_t MatchLength(const uint8_t *aPrefixA, const uint8_t *aPrefixB, uint8_t aMaxSize);
|
||
|
||
/**
|
||
* This method indicates whether or not the prefix has a valid length for use as a NAT64 prefix.
|
||
*
|
||
* A NAT64 prefix must have one of the following lengths: 32, 40, 48, 56, 64, or 96 (per RFC 6502).
|
||
*
|
||
* @retval TRUE If the prefix has a valid length for use as a NAT64 prefix.
|
||
* @retval FALSE If the prefix does not have a valid length for use as a NAT64 prefix.
|
||
*
|
||
*/
|
||
bool IsValidNat64(void) const;
|
||
|
||
/**
|
||
* This method converts the prefix to a string.
|
||
*
|
||
* The IPv6 prefix string is formatted as "%x:%x:%x:...[::]/plen".
|
||
*
|
||
* @returns An `InfoString` containing the string representation of the Prefix.
|
||
*
|
||
*/
|
||
InfoString ToString(void) const;
|
||
|
||
/**
|
||
* This method converts the prefix to a string.
|
||
*
|
||
* The IPv6 prefix string is formatted as "%x:%x:%x:...[::]/plen".
|
||
*
|
||
* If the resulting string does not fit in @p aBuffer (within its @p aSize characters), the string will be
|
||
* truncated but the outputted string is always null-terminated.
|
||
*
|
||
* @param[out] aBuffer A pointer to a char array to output the string (MUST NOT be `nullptr`).
|
||
* @param[in] aSize The size of @p aBuffer (in bytes).
|
||
*
|
||
*/
|
||
void ToString(char *aBuffer, uint16_t aSize) const;
|
||
|
||
private:
|
||
void ToString(StringWriter &aWriter) const;
|
||
} OT_TOOL_PACKED_END;
|
||
|
||
/**
|
||
* This class represents the Interface Identifier of an IPv6 address.
|
||
*
|
||
*/
|
||
OT_TOOL_PACKED_BEGIN
|
||
class InterfaceIdentifier : public otIp6InterfaceIdentifier,
|
||
public Equatable<InterfaceIdentifier>,
|
||
public Clearable<InterfaceIdentifier>
|
||
{
|
||
friend class Address;
|
||
|
||
public:
|
||
static constexpr uint8_t kSize = OT_IP6_IID_SIZE; ///< Size of an IPv6 Interface Identifier (in bytes).
|
||
|
||
static constexpr uint16_t kInfoStringSize = 17; ///< Max chars for the info string (`ToString()`).
|
||
|
||
/**
|
||
* This type defines the fixed-length `String` object returned from `ToString()`.
|
||
*
|
||
*/
|
||
typedef String<kInfoStringSize> InfoString;
|
||
|
||
/**
|
||
* This method indicates whether or not the Interface Identifier is unspecified.
|
||
*
|
||
* @retval true If the Interface Identifier is unspecified.
|
||
* @retval false If the Interface Identifier is not unspecified.
|
||
*
|
||
*/
|
||
bool IsUnspecified(void) const;
|
||
|
||
/**
|
||
* This method indicates whether or not the Interface Identifier is reserved (RFC 5453).
|
||
*
|
||
* @retval true If the Interface Identifier is reserved.
|
||
* @retval false If the Interface Identifier is not reserved.
|
||
*
|
||
*/
|
||
bool IsReserved(void) const;
|
||
|
||
/**
|
||
* This method indicates whether or not the Interface Identifier is Subnet-Router Anycast (RFC 4291).
|
||
*
|
||
* @retval TRUE If the Interface Identifier is a Subnet-Router Anycast address.
|
||
* @retval FALSE If the Interface Identifier is not a Subnet-Router Anycast address.
|
||
*
|
||
*/
|
||
bool IsSubnetRouterAnycast(void) const;
|
||
|
||
/**
|
||
* This method indicates whether or not the Interface Identifier is Reserved Subnet Anycast (RFC 2526).
|
||
*
|
||
* @retval TRUE If the Interface Identifier is a Reserved Subnet Anycast address.
|
||
* @retval FALSE If the Interface Identifier is not a Reserved Subnet Anycast address.
|
||
*
|
||
*/
|
||
bool IsReservedSubnetAnycast(void) const;
|
||
|
||
/**
|
||
* This method generates and sets the Interface Identifier to a crypto-secure random byte sequence.
|
||
*
|
||
*/
|
||
void GenerateRandom(void);
|
||
|
||
/**
|
||
* This method gets the Interface Identifier as a pointer to a byte array.
|
||
*
|
||
* @returns A pointer to a byte array (of size `kSize`) containing the Interface Identifier.
|
||
*
|
||
*/
|
||
const uint8_t *GetBytes(void) const { return mFields.m8; }
|
||
|
||
/**
|
||
* This method sets the Interface Identifier from a given byte array.
|
||
*
|
||
* @param[in] aBuffer Pointer to an array containing the Interface Identifier. `kSize` bytes from the buffer
|
||
* are copied to form the Interface Identifier.
|
||
*
|
||
*/
|
||
void SetBytes(const uint8_t *aBuffer);
|
||
|
||
/**
|
||
* This method sets the Interface Identifier from a given IEEE 802.15.4 Extended Address.
|
||
*
|
||
* @param[in] aExtAddress An Extended Address.
|
||
*
|
||
*/
|
||
void SetFromExtAddress(const Mac::ExtAddress &aExtAddress);
|
||
|
||
/**
|
||
* This method converts the Interface Identifier to an IEEE 802.15.4 Extended Address.
|
||
*
|
||
* @param[out] aExtAddress A reference to an Extended Address where the converted address is placed.
|
||
*
|
||
*/
|
||
void ConvertToExtAddress(Mac::ExtAddress &aExtAddress) const;
|
||
|
||
/**
|
||
* This method converts the Interface Identifier to an IEEE 802.15.4 MAC Address.
|
||
*
|
||
* @param[out] aMacAddress A reference to a MAC Address where the converted address is placed.
|
||
*
|
||
*/
|
||
void ConvertToMacAddress(Mac::Address &aMacAddress) const;
|
||
|
||
/**
|
||
* This method sets the Interface Identifier to Routing/Anycast Locator pattern `0000:00ff:fe00:xxxx` with a given
|
||
* locator (RLOC16 or ALOC16) value.
|
||
*
|
||
* @param[in] aLocator RLOC16 or ALOC16.
|
||
*
|
||
*/
|
||
void SetToLocator(uint16_t aLocator);
|
||
|
||
/**
|
||
* This method indicates whether or not the Interface Identifier matches the locator pattern `0000:00ff:fe00:xxxx`.
|
||
*
|
||
* @retval TRUE If the IID matches the locator pattern.
|
||
* @retval FALSE If the IID does not match the locator pattern.
|
||
*
|
||
*/
|
||
bool IsLocator(void) const;
|
||
|
||
/**
|
||
* This method indicates whether or not the Interface Identifier (IID) matches a Routing Locator (RLOC).
|
||
*
|
||
* In addition to checking that the IID matches the locator pattern (`0000:00ff:fe00:xxxx`), this method also
|
||
* checks that the locator value is a valid RLOC16.
|
||
*
|
||
* @retval TRUE If the IID matches a RLOC address.
|
||
* @retval FALSE If the IID does not match a RLOC address.
|
||
*
|
||
*/
|
||
bool IsRoutingLocator(void) const;
|
||
|
||
/**
|
||
* This method indicates whether or not the Interface Identifier (IID) matches an Anycast Locator (ALOC).
|
||
*
|
||
* In addition to checking that the IID matches the locator pattern (`0000:00ff:fe00:xxxx`), this method also
|
||
* checks that the locator value is any valid ALOC16 (0xfc00 - 0xfcff).
|
||
*
|
||
* @retval TRUE If the IID matches a ALOC address.
|
||
* @retval FALSE If the IID does not match a ALOC address.
|
||
*
|
||
*/
|
||
bool IsAnycastLocator(void) const;
|
||
|
||
/**
|
||
* This method indicates whether or not the Interface Identifier (IID) matches a Service Anycast Locator (ALOC).
|
||
*
|
||
* In addition to checking that the IID matches the locator pattern (`0000:00ff:fe00:xxxx`), this method also
|
||
* checks that the locator value is a valid Service ALOC16 (0xfc10 – 0xfc2f).
|
||
*
|
||
* @retval TRUE If the IID matches a ALOC address.
|
||
* @retval FALSE If the IID does not match a ALOC address.
|
||
*
|
||
*/
|
||
bool IsAnycastServiceLocator(void) const;
|
||
|
||
/**
|
||
* This method gets the Interface Identifier (IID) address locator fields.
|
||
*
|
||
* This method assumes the IID to match the locator pattern `0000:00ff:fe00:xxxx` (does not explicitly check this)
|
||
* and returns the last `uint16` portion of the IID.
|
||
*
|
||
* @returns The RLOC16 or ALOC16.
|
||
*
|
||
*/
|
||
uint16_t GetLocator(void) const { return HostSwap16(mFields.m16[3]); }
|
||
|
||
/**
|
||
* This method sets the Interface Identifier (IID) address locator field.
|
||
*
|
||
* Unlike `SetToLocator()`, this method only changes the last 2 bytes of the IID and keeps the rest of the address
|
||
* as before.
|
||
*
|
||
* @param[in] aLocator RLOC16 or ALOC16.
|
||
*
|
||
*/
|
||
void SetLocator(uint16_t aLocator) { mFields.m16[3] = HostSwap16(aLocator); }
|
||
|
||
/**
|
||
* This method converts an Interface Identifier to a string.
|
||
*
|
||
* @returns An `InfoString` containing the string representation of the Interface Identifier.
|
||
*
|
||
*/
|
||
InfoString ToString(void) const;
|
||
|
||
private:
|
||
static constexpr uint8_t kAloc16Mask = 0xfc; // The mask for ALOC16.
|
||
static constexpr uint8_t kRloc16ReservedBitMask = 0x02; // The mask for the reserved bit of RLOC16.
|
||
|
||
} OT_TOOL_PACKED_END;
|
||
|
||
/**
|
||
* This class implements an IPv6 address object.
|
||
*
|
||
*/
|
||
OT_TOOL_PACKED_BEGIN
|
||
class Address : public otIp6Address, public Equatable<Address>, public Clearable<Address>
|
||
{
|
||
friend class Prefix;
|
||
|
||
public:
|
||
static constexpr uint8_t kAloc16Mask = InterfaceIdentifier::kAloc16Mask; ///< The mask for ALOC16.
|
||
|
||
static constexpr uint8_t kSize = OT_IP6_ADDRESS_SIZE; ///< Size of an IPv6 Address (in bytes).
|
||
|
||
static constexpr uint16_t kInfoStringSize = OT_IP6_ADDRESS_STRING_SIZE; ///< String Size for IPv6 address.
|
||
|
||
// IPv6 Address Scopes
|
||
static constexpr uint8_t kNodeLocalScope = 0; ///< Node-Local scope
|
||
static constexpr uint8_t kInterfaceLocalScope = 1; ///< Interface-Local scope
|
||
static constexpr uint8_t kLinkLocalScope = 2; ///< Link-Local scope
|
||
static constexpr uint8_t kRealmLocalScope = 3; ///< Realm-Local scope
|
||
static constexpr uint8_t kAdminLocalScope = 4; ///< Admin-Local scope
|
||
static constexpr uint8_t kSiteLocalScope = 5; ///< Site-Local scope
|
||
static constexpr uint8_t kOrgLocalScope = 8; ///< Organization-Local scope
|
||
static constexpr uint8_t kGlobalScope = 14; ///< Global scope
|
||
|
||
/**
|
||
* This enumeration defines IPv6 address type filter.
|
||
*
|
||
*/
|
||
enum TypeFilter : uint8_t
|
||
{
|
||
kTypeAny, ///< Accept any IPv6 address (unicast or multicast).
|
||
kTypeUnicast, ///< Accept unicast IPv6 addresses only.
|
||
kTypeMulticast, ///< Accept multicast IPv6 addresses only.
|
||
kTypeMulticastLargerThanRealmLocal, ///< Accept multicast IPv6 addresses with scope larger than Realm Local.
|
||
};
|
||
|
||
/**
|
||
* This type defines the fixed-length `String` object returned from `ToString()`.
|
||
*
|
||
*/
|
||
typedef String<kInfoStringSize> InfoString;
|
||
|
||
/**
|
||
* This method gets the IPv6 address as a pointer to a byte array.
|
||
*
|
||
* @returns A pointer to a byte array containing the IPv6 address.
|
||
*
|
||
*/
|
||
const uint8_t *GetBytes(void) const { return mFields.m8; }
|
||
|
||
/**
|
||
* This method sets the IPv6 address from a given byte array.
|
||
*
|
||
* @param[in] aBuffer Pointer to an array containing the IPv6 address. `kSize` bytes from the buffer
|
||
* are copied to form the IPv6 address.
|
||
*
|
||
*/
|
||
void SetBytes(const uint8_t *aBuffer) { memcpy(mFields.m8, aBuffer, kSize); }
|
||
|
||
/**
|
||
* This method indicates whether or not the IPv6 address is the Unspecified Address.
|
||
*
|
||
* @retval TRUE If the IPv6 address is the Unspecified Address.
|
||
* @retval FALSE If the IPv6 address is not the Unspecified Address.
|
||
*
|
||
*/
|
||
bool IsUnspecified(void) const;
|
||
|
||
/**
|
||
* This method indicates whether or not the IPv6 address is the Loopback Address.
|
||
*
|
||
* @retval TRUE If the IPv6 address is the Loopback Address.
|
||
* @retval FALSE If the IPv6 address is not the Loopback Address.
|
||
*
|
||
*/
|
||
bool IsLoopback(void) const;
|
||
|
||
/**
|
||
* This method indicates whether or not the IPv6 address scope is Link-Local.
|
||
*
|
||
* @retval TRUE If the IPv6 address scope is Link-Local.
|
||
* @retval FALSE If the IPv6 address scope is not Link-Local.
|
||
*
|
||
*/
|
||
bool IsLinkLocal(void) const;
|
||
|
||
/**
|
||
* This methods sets the IPv6 address to a Link-Local address with Interface Identifier generated from a given
|
||
* MAC Extended Address.
|
||
*
|
||
* @param[in] aExtAddress A MAC Extended Address (used to generate the IID).
|
||
*
|
||
*/
|
||
void SetToLinkLocalAddress(const Mac::ExtAddress &aExtAddress);
|
||
|
||
/**
|
||
* This methods sets the IPv6 address to a Link-Local address with a given Interface Identifier.
|
||
*
|
||
* @param[in] aIid An Interface Identifier.
|
||
*
|
||
*/
|
||
void SetToLinkLocalAddress(const InterfaceIdentifier &aIid);
|
||
|
||
/**
|
||
* This method indicates whether or not the IPv6 address is multicast address.
|
||
*
|
||
* @retval TRUE If the IPv6 address is a multicast address.
|
||
* @retval FALSE If the IPv6 address scope is not a multicast address.
|
||
*
|
||
*/
|
||
bool IsMulticast(void) const { return mFields.m8[0] == 0xff; }
|
||
|
||
/**
|
||
* This method indicates whether or not the IPv6 address is a link-local multicast address.
|
||
*
|
||
* @retval TRUE If the IPv6 address is a link-local multicast address.
|
||
* @retval FALSE If the IPv6 address scope is not a link-local multicast address.
|
||
*
|
||
*/
|
||
bool IsLinkLocalMulticast(void) const;
|
||
|
||
/**
|
||
* This method indicates whether or not the IPv6 address is a link-local all nodes multicast address (ff02::01).
|
||
*
|
||
* @retval TRUE If the IPv6 address is a link-local all nodes multicast address.
|
||
* @retval FALSE If the IPv6 address is not a link-local all nodes multicast address.
|
||
*
|
||
*/
|
||
bool IsLinkLocalAllNodesMulticast(void) const;
|
||
|
||
/**
|
||
* This method sets the IPv6 address to the link-local all nodes multicast address (ff02::01).
|
||
*
|
||
*/
|
||
void SetToLinkLocalAllNodesMulticast(void);
|
||
|
||
/**
|
||
* This method indicates whether or not the IPv6 address is a link-local all routers multicast address (ff02::02).
|
||
*
|
||
* @retval TRUE If the IPv6 address is a link-local all routers multicast address.
|
||
* @retval FALSE If the IPv6 address is not a link-local all routers multicast address.
|
||
*
|
||
*/
|
||
bool IsLinkLocalAllRoutersMulticast(void) const;
|
||
|
||
/**
|
||
* This method sets the IPv6 address to the link-local all routers multicast address (ff02::02).
|
||
*
|
||
*/
|
||
void SetToLinkLocalAllRoutersMulticast(void);
|
||
|
||
/**
|
||
* This method indicates whether or not the IPv6 address is a realm-local multicast address.
|
||
*
|
||
* @retval TRUE If the IPv6 address is a realm-local multicast address.
|
||
* @retval FALSE If the IPv6 address scope is not a realm-local multicast address.
|
||
*
|
||
*/
|
||
bool IsRealmLocalMulticast(void) const;
|
||
|
||
/**
|
||
* This method indicates whether or not the IPv6 address is a realm-local all nodes multicast address (ff03::01).
|
||
*
|
||
* @retval TRUE If the IPv6 address is a realm-local all nodes multicast address.
|
||
* @retval FALSE If the IPv6 address is not a realm-local all nodes multicast address.
|
||
*
|
||
*/
|
||
bool IsRealmLocalAllNodesMulticast(void) const;
|
||
|
||
/**
|
||
* This method sets the IPv6 address to the realm-local all nodes multicast address (ff03::01)
|
||
*
|
||
*/
|
||
void SetToRealmLocalAllNodesMulticast(void);
|
||
|
||
/**
|
||
* This method indicates whether or not the IPv6 address is a realm-local all routers multicast address (ff03::02).
|
||
*
|
||
* @retval TRUE If the IPv6 address is a realm-local all routers multicast address.
|
||
* @retval FALSE If the IPv6 address is not a realm-local all routers multicast address.
|
||
*
|
||
*/
|
||
bool IsRealmLocalAllRoutersMulticast(void) const;
|
||
|
||
/**
|
||
* This method sets the IPv6 address to the realm-local all routers multicast address (ff03::02).
|
||
*
|
||
*/
|
||
void SetToRealmLocalAllRoutersMulticast(void);
|
||
|
||
/**
|
||
* This method indicates whether or not the IPv6 address is a realm-local all MPL forwarders address (ff03::fc).
|
||
*
|
||
* @retval TRUE If the IPv6 address is a realm-local all MPL forwarders address.
|
||
* @retval FALSE If the IPv6 address is not a realm-local all MPL forwarders address.
|
||
*
|
||
*/
|
||
bool IsRealmLocalAllMplForwarders(void) const;
|
||
|
||
/**
|
||
* This method sets the the IPv6 address to the realm-local all MPL forwarders address (ff03::fc).
|
||
*
|
||
*/
|
||
void SetToRealmLocalAllMplForwarders(void);
|
||
|
||
/**
|
||
* This method indicates whether or not the IPv6 address is multicast larger than realm local.
|
||
*
|
||
* @retval TRUE If the IPv6 address is multicast larger than realm local.
|
||
* @retval FALSE If the IPv6 address is not multicast or the scope is not larger than realm local.
|
||
*
|
||
*/
|
||
bool IsMulticastLargerThanRealmLocal(void) const;
|
||
|
||
/**
|
||
* This method sets the IPv6 address to a Routing Locator (RLOC) IPv6 address with a given Network Prefix and
|
||
* RLOC16 value.
|
||
*
|
||
* @param[in] aNetworkPrefix A Network Prefix.
|
||
* @param[in] aRloc16 A RLOC16 value.
|
||
*
|
||
*/
|
||
void SetToRoutingLocator(const NetworkPrefix &aNetworkPrefix, uint16_t aRloc16)
|
||
{
|
||
SetToLocator(aNetworkPrefix, aRloc16);
|
||
}
|
||
|
||
/**
|
||
* This method sets the IPv6 address to a Anycast Locator (ALOC) IPv6 address with a given Network Prefix and
|
||
* ALOC16 value.
|
||
*
|
||
* @param[in] aNetworkPrefix A Network Prefix.
|
||
* @param[in] aAloc16 A ALOC16 value.
|
||
*
|
||
*/
|
||
void SetToAnycastLocator(const NetworkPrefix &aNetworkPrefix, uint16_t aAloc16)
|
||
{
|
||
SetToLocator(aNetworkPrefix, aAloc16);
|
||
}
|
||
|
||
/**
|
||
* This method returns the Network Prefix of the IPv6 address (most significant 64 bits of the address).
|
||
*
|
||
* @returns A reference to the Network Prefix.
|
||
*
|
||
*/
|
||
const NetworkPrefix &GetPrefix(void) const
|
||
{
|
||
return static_cast<const NetworkPrefix &>(mFields.mComponents.mNetworkPrefix);
|
||
}
|
||
|
||
/**
|
||
* This method indicates whether the IPv6 address matches a given prefix.
|
||
*
|
||
* @param[in] aPrefix An IPv6 prefix to match with.
|
||
*
|
||
* @retval TRUE The IPv6 address matches the @p aPrefix.
|
||
* @retval FALSE The IPv6 address does not match the @p aPrefix.
|
||
*
|
||
*/
|
||
bool MatchesPrefix(const Prefix &aPrefix) const;
|
||
|
||
/**
|
||
* This method indicates whether the IPv6 address matches a given prefix.
|
||
*
|
||
* @param[in] aPrefix A buffer containing the prefix.
|
||
* @param[in] aPrefixLength The prefix length (in bits).
|
||
*
|
||
* @retval TRUE The IPv6 address matches the @p aPrefix.
|
||
* @retval FALSE The IPv6 address does not match the @p aPrefix.
|
||
*
|
||
*/
|
||
bool MatchesPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) const;
|
||
|
||
/**
|
||
* This method sets the IPv6 address prefix.
|
||
*
|
||
* This method only changes the first @p aPrefixLength bits of the address and keeps the rest of the bits in the
|
||
* address as before.
|
||
*
|
||
* @param[in] aPrefix A buffer containing the prefix.
|
||
* @param[in] aPrefixLength The prefix length (in bits).
|
||
*
|
||
*/
|
||
void SetPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) { SetPrefix(0, aPrefix, aPrefixLength); }
|
||
|
||
/**
|
||
* This method sets the IPv6 address prefix to the given Network Prefix.
|
||
*
|
||
* @param[in] aNetworkPrefix A Network Prefix.
|
||
*
|
||
*/
|
||
void SetPrefix(const NetworkPrefix &aNetworkPrefix);
|
||
|
||
/**
|
||
* This method sets the IPv6 address prefix.
|
||
*
|
||
* This method only changes the initial prefix length bits of the IPv6 address and keeps the rest of the bits in
|
||
* the address as before.
|
||
*
|
||
* @param[in] aPrefix An IPv6 prefix.
|
||
*
|
||
*/
|
||
void SetPrefix(const Prefix &aPrefix);
|
||
|
||
/**
|
||
* This method sets the prefix content of the Prefix-Based Multicast Address.
|
||
*
|
||
* @param[in] aPrefix A buffer containing the prefix.
|
||
* @param[in] aPrefixLength The prefix length (in bits).
|
||
*
|
||
*/
|
||
void SetMulticastNetworkPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength);
|
||
|
||
/**
|
||
* This method sets the prefix content of Prefix-Based Multicast Address.
|
||
*
|
||
* @param[in] aNetworkPrefix A reference to a Network Prefix.
|
||
*
|
||
*/
|
||
void SetMulticastNetworkPrefix(const NetworkPrefix &aNetworkPrefix)
|
||
{
|
||
SetMulticastNetworkPrefix(aNetworkPrefix.m8, NetworkPrefix::kLength);
|
||
}
|
||
|
||
/**
|
||
* This method sets the prefix content of Prefix-Based Multicast Address.
|
||
*
|
||
* @param[in] aPrefix An IPv6 Prefix.
|
||
*
|
||
*/
|
||
void SetMulticastNetworkPrefix(const Prefix &aPrefix)
|
||
{
|
||
SetMulticastNetworkPrefix(aPrefix.GetBytes(), aPrefix.GetLength());
|
||
}
|
||
|
||
/**
|
||
* This method returns the Interface Identifier of the IPv6 address.
|
||
*
|
||
* @returns A reference to the Interface Identifier.
|
||
*
|
||
*/
|
||
const InterfaceIdentifier &GetIid(void) const
|
||
{
|
||
return static_cast<const InterfaceIdentifier &>(mFields.mComponents.mIid);
|
||
}
|
||
|
||
/**
|
||
* This method returns the Interface Identifier of the IPv6 address.
|
||
*
|
||
* @returns A reference to the Interface Identifier.
|
||
*
|
||
*/
|
||
InterfaceIdentifier &GetIid(void) { return static_cast<InterfaceIdentifier &>(mFields.mComponents.mIid); }
|
||
|
||
/**
|
||
* This method sets the Interface Identifier.
|
||
*
|
||
* @param[in] aIid An Interface Identifier.
|
||
*
|
||
*/
|
||
void SetIid(const InterfaceIdentifier &aIid) { GetIid() = aIid; }
|
||
|
||
/**
|
||
* This method returns the IPv6 address scope.
|
||
*
|
||
* @returns The IPv6 address scope.
|
||
*
|
||
*/
|
||
uint8_t GetScope(void) const;
|
||
|
||
/**
|
||
* This method returns the number of IPv6 prefix bits that match.
|
||
*
|
||
* @param[in] aOther The IPv6 address to match against.
|
||
*
|
||
* @returns The number of IPv6 prefix bits that match.
|
||
*
|
||
*/
|
||
uint8_t PrefixMatch(const Address &aOther) const;
|
||
|
||
/**
|
||
* This method indicates whether address matches a given type filter.
|
||
*
|
||
* @param[in] aFilter An address type filter.
|
||
*
|
||
* @retval TRUE The address matches @p aFilter.
|
||
* @retval FALSE The address does not match @p aFilter.
|
||
*
|
||
*/
|
||
bool MatchesFilter(TypeFilter aFilter) const;
|
||
|
||
/**
|
||
* This method sets the IPv6 address by performing NAT64 address translation from a given IPv4 address as specified
|
||
* in RFC 6052.
|
||
*
|
||
* The NAT64 @p aPrefix MUST have one of the following lengths: 32, 40, 48, 56, 64, or 96, otherwise the behavior
|
||
* of this method is undefined.
|
||
*
|
||
* @param[in] aPrefix The prefix to use for IPv4/IPv6 translation.
|
||
* @param[in] aIp4Address The IPv4 address to translate to IPv6.
|
||
*
|
||
*/
|
||
void SynthesizeFromIp4Address(const Prefix &aPrefix, const Ip4::Address &aIp4Address);
|
||
|
||
/**
|
||
* This method converts an IPv6 address string to binary.
|
||
*
|
||
* @param[in] aString A pointer to the null-terminated string.
|
||
*
|
||
* @retval kErrorNone Successfully parsed the IPv6 address string.
|
||
* @retval kErrorParse Failed to parse the IPv6 address string.
|
||
*
|
||
*/
|
||
Error FromString(const char *aString);
|
||
|
||
/**
|
||
* This method converts the IPv6 address to a string.
|
||
*
|
||
* The IPv6 address string is formatted as 16 hex values separated by ':' (i.e., "%x:%x:%x:...:%x").
|
||
*
|
||
* @returns An `InfoString` representing the IPv6 address.
|
||
*
|
||
*/
|
||
InfoString ToString(void) const;
|
||
|
||
/**
|
||
* This method convert the IPv6 address to a C string.
|
||
*
|
||
* The IPv6 address string is formatted as 16 hex values separated by ':' (i.e., "%x:%x:%x:...:%x").
|
||
*
|
||
* If the resulting string does not fit in @p aBuffer (within its @p aSize characters), the string will be
|
||
* truncated but the outputted string is always null-terminated.
|
||
*
|
||
* @param[out] aBuffer A pointer to a char array to output the string (MUST NOT be `nullptr`).
|
||
* @param[in] aSize The size of @p aBuffer (in bytes).
|
||
*
|
||
*/
|
||
void ToString(char *aBuffer, uint16_t aSize) const;
|
||
|
||
/**
|
||
* This method overloads operator `<` to compare two IPv6 addresses.
|
||
*
|
||
* @param[in] aOther The other IPv6 address to compare with.
|
||
*
|
||
* @retval true The IPv6 address is smaller than @p aOther.
|
||
* @retval false The IPv6 address is larger than or equal to @p aOther.
|
||
*
|
||
*/
|
||
bool operator<(const Address &aOther) const { return memcmp(mFields.m8, aOther.mFields.m8, sizeof(Address)) < 0; }
|
||
|
||
private:
|
||
void SetPrefix(uint8_t aOffset, const uint8_t *aPrefix, uint8_t aPrefixLength);
|
||
void SetToLocator(const NetworkPrefix &aNetworkPrefix, uint16_t aLocator);
|
||
void ToString(StringWriter &aWriter) const;
|
||
void AppendHexWords(StringWriter &aWriter, uint8_t aLength) const;
|
||
|
||
static const Address &GetLinkLocalAllNodesMulticast(void);
|
||
static const Address &GetLinkLocalAllRoutersMulticast(void);
|
||
static const Address &GetRealmLocalAllNodesMulticast(void);
|
||
static const Address &GetRealmLocalAllRoutersMulticast(void);
|
||
static const Address &GetRealmLocalAllMplForwarders(void);
|
||
|
||
static constexpr uint8_t kMulticastNetworkPrefixLengthOffset = 3; // Prefix-Based Multicast Address (RFC3306).
|
||
static constexpr uint8_t kMulticastNetworkPrefixOffset = 4; // Prefix-Based Multicast Address (RFC3306).
|
||
} OT_TOOL_PACKED_END;
|
||
|
||
/**
|
||
* @}
|
||
*
|
||
*/
|
||
|
||
} // namespace Ip6
|
||
|
||
DefineCoreType(otIp6NetworkPrefix, Ip6::NetworkPrefix);
|
||
DefineCoreType(otIp6Prefix, Ip6::Prefix);
|
||
DefineCoreType(otIp6InterfaceIdentifier, Ip6::InterfaceIdentifier);
|
||
DefineCoreType(otIp6Address, Ip6::Address);
|
||
|
||
} // namespace ot
|
||
|
||
#endif // IP6_ADDRESS_HPP_
|