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 includes definitions for IPv6 addresses. 32 */ 33 34 #ifndef IP6_ADDRESS_HPP_ 35 #define IP6_ADDRESS_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include <openthread/ip6.h> 40 41 #include "common/as_core_type.hpp" 42 #include "common/clearable.hpp" 43 #include "common/encoding.hpp" 44 #include "common/equatable.hpp" 45 #include "common/num_utils.hpp" 46 #include "common/numeric_limits.hpp" 47 #include "common/string.hpp" 48 #include "mac/mac_types.hpp" 49 50 namespace ot { 51 52 namespace Ip4 { 53 // Forward declaration for SynthesizeFromIp4Address 54 class Address; 55 } // namespace Ip4 56 57 namespace Ip6 { 58 59 /** 60 * @addtogroup core-ip6-ip6 61 * 62 * @{ 63 */ 64 65 /** 66 * Represents the Network Prefix of an IPv6 address (most significant 64 bits of the address). 67 */ 68 OT_TOOL_PACKED_BEGIN 69 class NetworkPrefix : public otIp6NetworkPrefix, public Equatable<NetworkPrefix>, public Clearable<NetworkPrefix> 70 { 71 public: 72 static constexpr uint8_t kSize = OT_IP6_PREFIX_SIZE; ///< Size in bytes. 73 static constexpr uint8_t kLength = kSize * kBitsPerByte; ///< Length of Network Prefix in bits. 74 75 /** 76 * Generates and sets the Network Prefix to a crypto-secure random Unique Local Address (ULA) based 77 * on the pattern `fdxx:xxxx:xxxx:` (RFC 4193). 78 * 79 * @retval kErrorNone Successfully generated a random ULA Network Prefix 80 * @retval kErrorFailed Failed to generate random ULA Network Prefix. 81 */ 82 Error GenerateRandomUla(void); 83 84 } OT_TOOL_PACKED_END; 85 86 /** 87 * Represents an IPv6 Prefix. 88 */ 89 OT_TOOL_PACKED_BEGIN 90 class Prefix : public otIp6Prefix, public Clearable<Prefix>, public Unequatable<Prefix> 91 { 92 public: 93 static constexpr uint8_t kMaxSize = OT_IP6_ADDRESS_SIZE; ///< Max (byte) size of a prefix. 94 static constexpr uint8_t kMaxLength = kMaxSize * kBitsPerByte; ///< Max length of a prefix in bits. 95 96 static constexpr uint16_t kInfoStringSize = OT_IP6_PREFIX_STRING_SIZE; ///< Info string size (`ToString()`). 97 98 /** 99 * Defines the fixed-length `String` object returned from `ToString()`. 100 */ 101 typedef String<kInfoStringSize> InfoString; 102 103 /** 104 * Gets the prefix as a pointer to a byte array. 105 * 106 * @returns A pointer to a byte array containing the Prefix. 107 */ GetBytes(void) const108 const uint8_t *GetBytes(void) const { return mPrefix.mFields.m8; } 109 110 /** 111 * Gets the subnet ID of the prefix. 112 * 113 * @returns The 16-bit subnet ID. 114 */ GetSubnetId(void) const115 uint16_t GetSubnetId(void) const { return BigEndian::HostSwap16(mPrefix.mFields.m16[3]); } 116 117 /** 118 * Gets the prefix length (in bits). 119 * 120 * @returns The prefix length (in bits). 121 */ GetLength(void) const122 uint8_t GetLength(void) const { return mLength; } 123 124 /** 125 * Returns the size (in bytes) of the prefix. 126 * 127 * @returns The size (in bytes) of the prefix array. 128 */ GetBytesSize(void) const129 uint8_t GetBytesSize(void) const { return SizeForLength(mLength); } 130 131 /** 132 * Sets the prefix. 133 * 134 * @param[in] aPrefix A pointer to buffer containing the prefix bytes. 135 * @param[in] aLength The length or prefix in bits. 136 */ 137 void Set(const uint8_t *aPrefix, uint8_t aLength); 138 139 /** 140 * Sets the prefix from a given Network Prefix. 141 * 142 * @param[in] aNetworkPrefix A Network Prefix. 143 */ Set(const NetworkPrefix & aNetworkPrefix)144 void Set(const NetworkPrefix &aNetworkPrefix) { Set(aNetworkPrefix.m8, NetworkPrefix::kLength); } 145 146 /** 147 * Sets the subnet ID of the prefix. 148 * 149 * @param[in] aSubnetId A 16-bit subnet ID. 150 */ SetSubnetId(uint16_t aSubnetId)151 void SetSubnetId(uint16_t aSubnetId) { mPrefix.mFields.m16[3] = BigEndian::HostSwap16(aSubnetId); } 152 153 /** 154 * Set the prefix length. 155 * 156 * @param[in] aLength The new prefix length (in bits). 157 */ SetLength(uint8_t aLength)158 void SetLength(uint8_t aLength) { mLength = aLength; } 159 160 /** 161 * Sets the bits after the prefix length to 0. 162 */ 163 void Tidy(void); 164 165 /** 166 * Indicates whether prefix length is valid (smaller or equal to max length). 167 * 168 * @retval TRUE The prefix length is valid. 169 * @retval FALSE The prefix length is not valid. 170 */ IsValid(void) const171 bool IsValid(void) const { return (mLength <= kMaxLength); } 172 173 /** 174 * Indicates whether the prefix is a Link-Local prefix. 175 * 176 * @retval TRUE The prefix is a Link-Local prefix. 177 * @retval FALSE The prefix is not a Link-Local prefix. 178 */ 179 bool IsLinkLocal(void) const; 180 181 /** 182 * Indicates whether the prefix is a Multicast prefix. 183 * 184 * @retval TRUE The prefix is a Multicast prefix. 185 * @retval FALSE The prefix is not a Multicast prefix. 186 */ 187 bool IsMulticast(void) const; 188 189 /** 190 * Indicates whether the prefix is a Unique-Local prefix. 191 * 192 * @retval TRUE The prefix is a Unique-Local prefix. 193 * @retval FALSE The prefix is not a Unique-Local prefix. 194 */ 195 bool IsUniqueLocal(void) const; 196 197 /** 198 * Indicates whether the prefix is equal to a given prefix. 199 * 200 * @param[in] aPrefixBytes A pointer to buffer containing the prefix bytes to compare with. 201 * @param[in] aPrefixLength The length of prefix (in bits) specified by @p aPrefixBytes. 202 * 203 * @retval TRUE If the prefix is equal to the specified prefix by @p aPrefixBytes and @p aPrefixLength. 204 * @retval FALSE If the prefix is not equal to the specified prefix by @p aPrefixBytes and @p aPrefixLength. 205 */ 206 bool IsEqual(const uint8_t *aPrefixBytes, uint8_t aPrefixLength) const; 207 208 /** 209 * Indicates whether the prefix contains a sub-prefix. 210 * 211 * @param[in] aSubPrefix A sub-prefix. 212 * 213 * @retval TRUE The prefix contains the @p aSubPrefix 214 * @retval FALSE The prefix does not contains the @p aSubPrefix. 215 */ 216 bool ContainsPrefix(const Prefix &aSubPrefix) const; 217 218 /** 219 * Indicates whether the prefix contains a sub-prefix (given as a `NetworkPrefix`). 220 * 221 * @param[in] aSubPrefix A sub-prefix (as a `NetworkPrefix`). 222 * 223 * @retval TRUE The prefix contains the @p aSubPrefix 224 * @retval FALSE The prefix does not contains the @p aSubPrefix. 225 */ 226 bool ContainsPrefix(const NetworkPrefix &aSubPrefix) const; 227 228 /** 229 * Overloads operator `==` to evaluate whether or not two prefixes are equal. 230 * 231 * @param[in] aOther The other prefix to compare with. 232 * 233 * @retval TRUE If the two prefixes are equal. 234 * @retval FALSE If the two prefixes are not equal. 235 */ 236 bool operator==(const Prefix &aOther) const; 237 238 /** 239 * Overloads operator `<` to compare two prefixes. 240 * 241 * If the two prefixes have the same length N, then the bytes are compared directly (as two big-endian N-bit 242 * numbers). If the two prefix have different lengths, the shorter prefix is padded by `0` bit up to the longer 243 * prefix length N before the bytes are compared (as big-endian N-bit numbers). If all bytes are equal, the prefix 244 * with shorter length is considered smaller. 245 * 246 * @param[in] aOther The other prefix to compare against. 247 * 248 * @retval TRUE If the prefix is smaller than @p aOther. 249 * @retval FALSE If the prefix is not smaller than @p aOther. 250 */ 251 bool operator<(const Prefix &aOther) const; 252 253 /** 254 * Converts a prefix length (in bits) to size (number of bytes). 255 * 256 * @param[in] aLength A prefix length (in bits). 257 * 258 * @returns The size (in bytes) of the prefix. 259 */ SizeForLength(uint8_t aLength)260 static uint8_t SizeForLength(uint8_t aLength) { return BytesForBitSize(aLength); } 261 262 /** 263 * Returns the number of IPv6 prefix bits that match. 264 * 265 * @param[in] aPrefixA A pointer to a byte array containing a first prefix. 266 * @param[in] aPrefixB A pointer to a byte array containing a second prefix. 267 * @param[in] aMaxSize Number of bytes of the two prefixes. 268 * 269 * @returns The number of prefix bits that match. 270 */ 271 static uint8_t MatchLength(const uint8_t *aPrefixA, const uint8_t *aPrefixB, uint8_t aMaxSize); 272 273 /** 274 * Indicates whether or not a given prefix length is valid for use as a NAT64 prefix. 275 * 276 * A NAT64 prefix must have one of the following lengths: 32, 40, 48, 56, 64, or 96 (per RFC 6052). 277 * 278 * @param[in] aLength The length of the prefix. 279 * 280 * @retval TRUE If the prefix has a valid length for use as a NAT64 prefix. 281 * @retval FALSE If the prefix does not have a valid length for use as a NAT64 prefix. 282 */ 283 static bool IsValidNat64PrefixLength(uint8_t aLength); 284 285 /** 286 * Indicates whether or not the prefix has a valid length for use as a NAT64 prefix. 287 * 288 * A NAT64 prefix must have one of the following lengths: 32, 40, 48, 56, 64, or 96 (per RFC 6052). 289 * 290 * @retval TRUE If the prefix has a valid length for use as a NAT64 prefix. 291 * @retval FALSE If the prefix does not have a valid length for use as a NAT64 prefix. 292 */ IsValidNat64(void) const293 bool IsValidNat64(void) const { return IsValidNat64PrefixLength(mLength); } 294 295 /** 296 * Parses a given IPv6 prefix string and sets the prefix. 297 * 298 * @param[in] aString A null-terminated string, with format "<prefix>/<plen>" 299 * 300 * @retval kErrorNone Successfully parsed the IPv6 prefix from @p aString. 301 * @retval kErrorParse Failed to parse the IPv6 prefix from @p aString. 302 */ 303 Error FromString(const char *aString); 304 305 /** 306 * Converts the prefix to a string. 307 * 308 * The IPv6 prefix string is formatted as "%x:%x:%x:...[::]/plen". 309 * 310 * @returns An `InfoString` containing the string representation of the Prefix. 311 */ 312 InfoString ToString(void) const; 313 314 /** 315 * Converts the prefix to a string. 316 * 317 * The IPv6 prefix string is formatted as "%x:%x:%x:...[::]/plen". 318 * 319 * If the resulting string does not fit in @p aBuffer (within its @p aSize characters), the string will be 320 * truncated but the outputted string is always null-terminated. 321 * 322 * @param[out] aBuffer A pointer to a char array to output the string (MUST NOT be `nullptr`). 323 * @param[in] aSize The size of @p aBuffer (in bytes). 324 */ 325 void ToString(char *aBuffer, uint16_t aSize) const; 326 327 private: 328 uint8_t ByteAfterTidy(uint8_t aIndex); 329 void ToString(StringWriter &aWriter) const; 330 } OT_TOOL_PACKED_END; 331 332 /** 333 * Represents the Interface Identifier of an IPv6 address. 334 */ 335 OT_TOOL_PACKED_BEGIN 336 class InterfaceIdentifier : public otIp6InterfaceIdentifier, 337 public Equatable<InterfaceIdentifier>, 338 public Clearable<InterfaceIdentifier> 339 { 340 friend class Address; 341 342 public: 343 static constexpr uint8_t kSize = OT_IP6_IID_SIZE; ///< Size of an IPv6 Interface Identifier (in bytes). 344 345 static constexpr uint16_t kInfoStringSize = 17; ///< Max chars for the info string (`ToString()`). 346 347 /** 348 * Defines the fixed-length `String` object returned from `ToString()`. 349 */ 350 typedef String<kInfoStringSize> InfoString; 351 352 /** 353 * Indicates whether or not the Interface Identifier is unspecified. 354 * 355 * @retval true If the Interface Identifier is unspecified. 356 * @retval false If the Interface Identifier is not unspecified. 357 */ 358 bool IsUnspecified(void) const; 359 360 /** 361 * Indicates whether or not the Interface Identifier is reserved (RFC 5453). 362 * 363 * @retval true If the Interface Identifier is reserved. 364 * @retval false If the Interface Identifier is not reserved. 365 */ 366 bool IsReserved(void) const; 367 368 /** 369 * Indicates whether or not the Interface Identifier is Subnet-Router Anycast (RFC 4291). 370 * 371 * @retval TRUE If the Interface Identifier is a Subnet-Router Anycast address. 372 * @retval FALSE If the Interface Identifier is not a Subnet-Router Anycast address. 373 */ 374 bool IsSubnetRouterAnycast(void) const; 375 376 /** 377 * Indicates whether or not the Interface Identifier is Reserved Subnet Anycast (RFC 2526). 378 * 379 * @retval TRUE If the Interface Identifier is a Reserved Subnet Anycast address. 380 * @retval FALSE If the Interface Identifier is not a Reserved Subnet Anycast address. 381 */ 382 bool IsReservedSubnetAnycast(void) const; 383 384 /** 385 * Generates and sets the Interface Identifier to a crypto-secure random byte sequence. 386 */ 387 void GenerateRandom(void); 388 389 /** 390 * Gets the Interface Identifier as a pointer to a byte array. 391 * 392 * @returns A pointer to a byte array (of size `kSize`) containing the Interface Identifier. 393 */ GetBytes(void) const394 const uint8_t *GetBytes(void) const { return mFields.m8; } 395 396 /** 397 * Sets the Interface Identifier from a given byte array. 398 * 399 * @param[in] aBuffer Pointer to an array containing the Interface Identifier. `kSize` bytes from the buffer 400 * are copied to form the Interface Identifier. 401 */ 402 void SetBytes(const uint8_t *aBuffer); 403 404 /** 405 * Sets the Interface Identifier from a given IEEE 802.15.4 Extended Address. 406 * 407 * @param[in] aExtAddress An Extended Address. 408 */ 409 void SetFromExtAddress(const Mac::ExtAddress &aExtAddress); 410 411 /** 412 * Converts the Interface Identifier to an IEEE 802.15.4 Extended Address. 413 * 414 * @param[out] aExtAddress A reference to an Extended Address where the converted address is placed. 415 */ 416 void ConvertToExtAddress(Mac::ExtAddress &aExtAddress) const; 417 418 /** 419 * Converts the Interface Identifier to an IEEE 802.15.4 MAC Address. 420 * 421 * @param[out] aMacAddress A reference to a MAC Address where the converted address is placed. 422 */ 423 void ConvertToMacAddress(Mac::Address &aMacAddress) const; 424 425 /** 426 * Sets the Interface Identifier to Routing/Anycast Locator pattern `0000:00ff:fe00:xxxx` with a given 427 * locator (RLOC16 or ALOC16) value. 428 * 429 * @param[in] aLocator RLOC16 or ALOC16. 430 */ 431 void SetToLocator(uint16_t aLocator); 432 433 /** 434 * Indicates whether or not the Interface Identifier matches the locator pattern `0000:00ff:fe00:xxxx`. 435 * 436 * @retval TRUE If the IID matches the locator pattern. 437 * @retval FALSE If the IID does not match the locator pattern. 438 */ 439 bool IsLocator(void) const; 440 441 /** 442 * Indicates whether or not the Interface Identifier (IID) matches a Routing Locator (RLOC). 443 * 444 * In addition to checking that the IID matches the locator pattern (`0000:00ff:fe00:xxxx`), this method also 445 * checks that the locator value is a valid RLOC16. 446 * 447 * @retval TRUE If the IID matches a RLOC address. 448 * @retval FALSE If the IID does not match a RLOC address. 449 */ 450 bool IsRoutingLocator(void) const; 451 452 /** 453 * Indicates whether or not the Interface Identifier (IID) matches an Anycast Locator (ALOC). 454 * 455 * In addition to checking that the IID matches the locator pattern (`0000:00ff:fe00:xxxx`), this method also 456 * checks that the locator value is any valid ALOC16 (0xfc00 - 0xfcff). 457 * 458 * @retval TRUE If the IID matches a ALOC address. 459 * @retval FALSE If the IID does not match a ALOC address. 460 */ 461 bool IsAnycastLocator(void) const; 462 463 /** 464 * Indicates whether or not the Interface Identifier (IID) matches a Service Anycast Locator (ALOC). 465 * 466 * In addition to checking that the IID matches the locator pattern (`0000:00ff:fe00:xxxx`), this method also 467 * checks that the locator value is a valid Service ALOC16 (0xfc10 – 0xfc2f). 468 * 469 * @retval TRUE If the IID matches a ALOC address. 470 * @retval FALSE If the IID does not match a ALOC address. 471 */ 472 bool IsAnycastServiceLocator(void) const; 473 474 /** 475 * Gets the Interface Identifier (IID) address locator fields. 476 * 477 * Assumes the IID to match the locator pattern `0000:00ff:fe00:xxxx` (does not explicitly check this) 478 * and returns the last `uint16` portion of the IID. 479 * 480 * @returns The RLOC16 or ALOC16. 481 */ GetLocator(void) const482 uint16_t GetLocator(void) const { return BigEndian::HostSwap16(mFields.m16[3]); } 483 484 /** 485 * Sets the Interface Identifier (IID) address locator field. 486 * 487 * Unlike `SetToLocator()`, this method only changes the last 2 bytes of the IID and keeps the rest of the address 488 * as before. 489 * 490 * @param[in] aLocator RLOC16 or ALOC16. 491 */ SetLocator(uint16_t aLocator)492 void SetLocator(uint16_t aLocator) { mFields.m16[3] = BigEndian::HostSwap16(aLocator); } 493 494 /** 495 * Applies a prefix to IID. 496 * 497 * If the prefix length is longer than 64 bits, the prefix bits after 64 are written into the IID. This method only 498 * changes the bits in IID up the prefix length and keeps the rest of the bits in IID as before. 499 * 500 * @param[in] aPrefix An IPv6 prefix. 501 */ 502 void ApplyPrefix(const Prefix &aPrefix); 503 504 /** 505 * Converts an Interface Identifier to a string. 506 * 507 * @returns An `InfoString` containing the string representation of the Interface Identifier. 508 */ 509 InfoString ToString(void) const; 510 511 private: 512 static constexpr uint8_t kAloc16Mask = 0xfc; // The mask for ALOC16. 513 static constexpr uint8_t kRloc16ReservedBitMask = 0x02; // The mask for the reserved bit of RLOC16. 514 515 } OT_TOOL_PACKED_END; 516 517 /** 518 * Implements an IPv6 address object. 519 */ 520 OT_TOOL_PACKED_BEGIN 521 class Address : public otIp6Address, public Equatable<Address>, public Clearable<Address> 522 { 523 friend class Prefix; 524 friend class InterfaceIdentifier; 525 526 public: 527 static constexpr uint8_t kAloc16Mask = InterfaceIdentifier::kAloc16Mask; ///< The mask for ALOC16. 528 529 static constexpr uint8_t kSize = OT_IP6_ADDRESS_SIZE; ///< Size of an IPv6 Address (in bytes). 530 531 static constexpr uint16_t kInfoStringSize = OT_IP6_ADDRESS_STRING_SIZE; ///< String Size for IPv6 address. 532 533 // IPv6 Address Scopes 534 static constexpr uint8_t kNodeLocalScope = 0; ///< Node-Local scope 535 static constexpr uint8_t kInterfaceLocalScope = 1; ///< Interface-Local scope 536 static constexpr uint8_t kLinkLocalScope = 2; ///< Link-Local scope 537 static constexpr uint8_t kRealmLocalScope = 3; ///< Realm-Local scope 538 static constexpr uint8_t kAdminLocalScope = 4; ///< Admin-Local scope 539 static constexpr uint8_t kSiteLocalScope = 5; ///< Site-Local scope 540 static constexpr uint8_t kOrgLocalScope = 8; ///< Organization-Local scope 541 static constexpr uint8_t kGlobalScope = 14; ///< Global scope 542 543 /** 544 * Defines IPv6 address type filter. 545 */ 546 enum TypeFilter : uint8_t 547 { 548 kTypeAny, ///< Accept any IPv6 address (unicast or multicast). 549 kTypeUnicast, ///< Accept unicast IPv6 addresses only. 550 kTypeMulticast, ///< Accept multicast IPv6 addresses only. 551 kTypeMulticastLargerThanRealmLocal, ///< Accept multicast IPv6 addresses with scope larger than Realm Local. 552 }; 553 554 /** 555 * Defines the fixed-length `String` object returned from `ToString()`. 556 */ 557 typedef String<kInfoStringSize> InfoString; 558 559 /** 560 * Gets the IPv6 address as a pointer to a byte array. 561 * 562 * @returns A pointer to a byte array containing the IPv6 address. 563 */ GetBytes(void) const564 const uint8_t *GetBytes(void) const { return mFields.m8; } 565 566 /** 567 * Sets the IPv6 address from a given byte array. 568 * 569 * @param[in] aBuffer Pointer to an array containing the IPv6 address. `kSize` bytes from the buffer 570 * are copied to form the IPv6 address. 571 */ SetBytes(const uint8_t * aBuffer)572 void SetBytes(const uint8_t *aBuffer) { memcpy(mFields.m8, aBuffer, kSize); } 573 574 /** 575 * Indicates whether or not the IPv6 address is the Unspecified Address. 576 * 577 * @retval TRUE If the IPv6 address is the Unspecified Address. 578 * @retval FALSE If the IPv6 address is not the Unspecified Address. 579 */ 580 bool IsUnspecified(void) const; 581 582 /** 583 * Indicates whether or not the IPv6 address is the Loopback Address. 584 * 585 * @retval TRUE If the IPv6 address is the Loopback Address. 586 * @retval FALSE If the IPv6 address is not the Loopback Address. 587 */ 588 bool IsLoopback(void) const; 589 590 /** 591 * Indicates whether or not the IPv6 address is a Link-Local unicast address. 592 * 593 * @retval TRUE If the IPv6 address is a Link-Local unicast address. 594 * @retval FALSE If the IPv6 address is not a Link-Local unicast address. 595 */ 596 bool IsLinkLocalUnicast(void) const; 597 598 /** 599 * Sets the IPv6 address to a Link-Local address with Interface Identifier generated from a given 600 * MAC Extended Address. 601 * 602 * @param[in] aExtAddress A MAC Extended Address (used to generate the IID). 603 */ 604 void SetToLinkLocalAddress(const Mac::ExtAddress &aExtAddress); 605 606 /** 607 * Sets the IPv6 address to a Link-Local address with a given Interface Identifier. 608 * 609 * @param[in] aIid An Interface Identifier. 610 */ 611 void SetToLinkLocalAddress(const InterfaceIdentifier &aIid); 612 613 /** 614 * Indicates whether or not the IPv6 address is multicast address. 615 * 616 * @retval TRUE If the IPv6 address is a multicast address. 617 * @retval FALSE If the IPv6 address scope is not a multicast address. 618 */ IsMulticast(void) const619 bool IsMulticast(void) const { return mFields.m8[0] == 0xff; } 620 621 /** 622 * Indicates whether or not the IPv6 address is a link-local multicast address. 623 * 624 * @retval TRUE If the IPv6 address is a link-local multicast address. 625 * @retval FALSE If the IPv6 address scope is not a link-local multicast address. 626 */ 627 bool IsLinkLocalMulticast(void) const; 628 629 /** 630 * Indicates whether or not the IPv6 address is a link-local unicast or a link-local multicast address. 631 * 632 * @retval TRUE If the IPv6 address is a link-local unicast or multicast address. 633 * @retval FALSE If the IPv6 address is not a link-local unicast and not a link-local multicast address. 634 */ 635 bool IsLinkLocalUnicastOrMulticast(void) const; 636 637 /** 638 * Indicates whether or not the IPv6 address is a link-local all nodes multicast address (ff02::01). 639 * 640 * @retval TRUE If the IPv6 address is a link-local all nodes multicast address. 641 * @retval FALSE If the IPv6 address is not a link-local all nodes multicast address. 642 */ 643 bool IsLinkLocalAllNodesMulticast(void) const; 644 645 /** 646 * Sets the IPv6 address to the link-local all nodes multicast address (ff02::01). 647 */ 648 void SetToLinkLocalAllNodesMulticast(void); 649 650 /** 651 * Indicates whether or not the IPv6 address is a link-local all routers multicast address (ff02::02). 652 * 653 * @retval TRUE If the IPv6 address is a link-local all routers multicast address. 654 * @retval FALSE If the IPv6 address is not a link-local all routers multicast address. 655 */ 656 bool IsLinkLocalAllRoutersMulticast(void) const; 657 658 /** 659 * Sets the IPv6 address to the link-local all routers multicast address (ff02::02). 660 */ 661 void SetToLinkLocalAllRoutersMulticast(void); 662 663 /** 664 * Indicates whether or not the IPv6 address is a realm-local multicast address. 665 * 666 * @retval TRUE If the IPv6 address is a realm-local multicast address. 667 * @retval FALSE If the IPv6 address scope is not a realm-local multicast address. 668 */ 669 bool IsRealmLocalMulticast(void) const; 670 671 /** 672 * Indicates whether or not the IPv6 address is a realm-local all nodes multicast address (ff03::01). 673 * 674 * @retval TRUE If the IPv6 address is a realm-local all nodes multicast address. 675 * @retval FALSE If the IPv6 address is not a realm-local all nodes multicast address. 676 */ 677 bool IsRealmLocalAllNodesMulticast(void) const; 678 679 /** 680 * Sets the IPv6 address to the realm-local all nodes multicast address (ff03::01) 681 */ 682 void SetToRealmLocalAllNodesMulticast(void); 683 684 /** 685 * Indicates whether or not the IPv6 address is a realm-local all routers multicast address (ff03::02). 686 * 687 * @retval TRUE If the IPv6 address is a realm-local all routers multicast address. 688 * @retval FALSE If the IPv6 address is not a realm-local all routers multicast address. 689 */ 690 bool IsRealmLocalAllRoutersMulticast(void) const; 691 692 /** 693 * Sets the IPv6 address to the realm-local all routers multicast address (ff03::02). 694 */ 695 void SetToRealmLocalAllRoutersMulticast(void); 696 697 /** 698 * Indicates whether or not the IPv6 address is a realm-local all MPL forwarders address (ff03::fc). 699 * 700 * @retval TRUE If the IPv6 address is a realm-local all MPL forwarders address. 701 * @retval FALSE If the IPv6 address is not a realm-local all MPL forwarders address. 702 */ 703 bool IsRealmLocalAllMplForwarders(void) const; 704 705 /** 706 * Sets the the IPv6 address to the realm-local all MPL forwarders address (ff03::fc). 707 */ 708 void SetToRealmLocalAllMplForwarders(void); 709 710 /** 711 * Indicates whether or not the IPv6 address is multicast larger than realm local. 712 * 713 * @retval TRUE If the IPv6 address is multicast larger than realm local. 714 * @retval FALSE If the IPv6 address is not multicast or the scope is not larger than realm local. 715 */ 716 bool IsMulticastLargerThanRealmLocal(void) const; 717 718 /** 719 * Sets the IPv6 address to a Routing Locator (RLOC) IPv6 address with a given Network Prefix and 720 * RLOC16 value. 721 * 722 * @param[in] aNetworkPrefix A Network Prefix. 723 * @param[in] aRloc16 A RLOC16 value. 724 */ SetToRoutingLocator(const NetworkPrefix & aNetworkPrefix,uint16_t aRloc16)725 void SetToRoutingLocator(const NetworkPrefix &aNetworkPrefix, uint16_t aRloc16) 726 { 727 SetToLocator(aNetworkPrefix, aRloc16); 728 } 729 730 /** 731 * Sets the IPv6 address to a Anycast Locator (ALOC) IPv6 address with a given Network Prefix and 732 * ALOC16 value. 733 * 734 * @param[in] aNetworkPrefix A Network Prefix. 735 * @param[in] aAloc16 A ALOC16 value. 736 */ SetToAnycastLocator(const NetworkPrefix & aNetworkPrefix,uint16_t aAloc16)737 void SetToAnycastLocator(const NetworkPrefix &aNetworkPrefix, uint16_t aAloc16) 738 { 739 SetToLocator(aNetworkPrefix, aAloc16); 740 } 741 742 /** 743 * Indicates whether or not the IPv6 address follows the IPv4-mapped format. 744 * 745 * An IPv4-mapped IPv6 address consists of an 80-bit prefix of zeros, the next 16 bits set to ones, and the 746 * remaining, least-significant 32 bits contain the IPv4 address, e.g., `::ffff:192.0.2.128` representing 747 * `192.0.2.128` IPv4 address. 748 * 749 * @retval TRUE If the IPv6 address follows the IPv4-mapped format. 750 * @retval FALSE If the IPv6 address does not follow the IPv4-mapped format. 751 */ 752 bool IsIp4Mapped(void) const; 753 754 /** 755 * Sets the IPv6 address to follow the IPv4-mapped IPv6 address for a given IPv4 address. 756 * 757 * @param[in] aIp4Address An IPv4 address. 758 */ 759 void SetToIp4Mapped(const Ip4::Address &aIp4Address); 760 761 /** 762 * Returns the Network Prefix of the IPv6 address (most significant 64 bits of the address). 763 * 764 * @returns A reference to the Network Prefix. 765 */ GetPrefix(void) const766 const NetworkPrefix &GetPrefix(void) const 767 { 768 return static_cast<const NetworkPrefix &>(mFields.mComponents.mNetworkPrefix); 769 } 770 771 /** 772 * Gets a prefix of the IPv6 address with a given length. 773 * 774 * @param[in] aLength The length of prefix in bits. 775 * @param[out] aPrefix A reference to a prefix to output the fetched prefix. 776 */ GetPrefix(uint8_t aLength,Prefix & aPrefix) const777 void GetPrefix(uint8_t aLength, Prefix &aPrefix) const { aPrefix.Set(mFields.m8, aLength); } 778 779 /** 780 * Indicates whether the IPv6 address matches a given prefix. 781 * 782 * @param[in] aPrefix An IPv6 prefix to match with. 783 * 784 * @retval TRUE The IPv6 address matches the @p aPrefix. 785 * @retval FALSE The IPv6 address does not match the @p aPrefix. 786 */ 787 bool MatchesPrefix(const Prefix &aPrefix) const; 788 789 /** 790 * Indicates whether the IPv6 address matches a given prefix. 791 * 792 * @param[in] aPrefix A buffer containing the prefix. 793 * @param[in] aPrefixLength The prefix length (in bits). 794 * 795 * @retval TRUE The IPv6 address matches the @p aPrefix. 796 * @retval FALSE The IPv6 address does not match the @p aPrefix. 797 */ 798 bool MatchesPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) const; 799 800 /** 801 * Sets the IPv6 address prefix. 802 * 803 * Only changes the first @p aPrefixLength bits of the address and keeps the rest of the bits in the 804 * address as before. 805 * 806 * @param[in] aPrefix A buffer containing the prefix. 807 * @param[in] aPrefixLength The prefix length (in bits). 808 */ SetPrefix(const uint8_t * aPrefix,uint8_t aPrefixLength)809 void SetPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) { CopyBits(mFields.m8, aPrefix, aPrefixLength); } 810 811 /** 812 * Sets the IPv6 address prefix to the given Network Prefix. 813 * 814 * @param[in] aNetworkPrefix A Network Prefix. 815 */ 816 void SetPrefix(const NetworkPrefix &aNetworkPrefix); 817 818 /** 819 * Sets the IPv6 address prefix. 820 * 821 * Only changes the initial prefix length bits of the IPv6 address and keeps the rest of the bits in 822 * the address as before. 823 * 824 * @param[in] aPrefix An IPv6 prefix. 825 */ 826 void SetPrefix(const Prefix &aPrefix); 827 828 /** 829 * Sets the prefix content of the Prefix-Based Multicast Address. 830 * 831 * @param[in] aPrefix A buffer containing the prefix. 832 * @param[in] aPrefixLength The prefix length (in bits). 833 */ 834 void SetMulticastNetworkPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength); 835 836 /** 837 * Sets the prefix content of Prefix-Based Multicast Address. 838 * 839 * @param[in] aNetworkPrefix A reference to a Network Prefix. 840 */ SetMulticastNetworkPrefix(const NetworkPrefix & aNetworkPrefix)841 void SetMulticastNetworkPrefix(const NetworkPrefix &aNetworkPrefix) 842 { 843 SetMulticastNetworkPrefix(aNetworkPrefix.m8, NetworkPrefix::kLength); 844 } 845 846 /** 847 * Sets the prefix content of Prefix-Based Multicast Address. 848 * 849 * @param[in] aPrefix An IPv6 Prefix. 850 */ SetMulticastNetworkPrefix(const Prefix & aPrefix)851 void SetMulticastNetworkPrefix(const Prefix &aPrefix) 852 { 853 SetMulticastNetworkPrefix(aPrefix.GetBytes(), aPrefix.GetLength()); 854 } 855 856 /** 857 * Returns the Interface Identifier of the IPv6 address. 858 * 859 * @returns A reference to the Interface Identifier. 860 */ GetIid(void) const861 const InterfaceIdentifier &GetIid(void) const 862 { 863 return static_cast<const InterfaceIdentifier &>(mFields.mComponents.mIid); 864 } 865 866 /** 867 * Returns the Interface Identifier of the IPv6 address. 868 * 869 * @returns A reference to the Interface Identifier. 870 */ GetIid(void)871 InterfaceIdentifier &GetIid(void) { return static_cast<InterfaceIdentifier &>(mFields.mComponents.mIid); } 872 873 /** 874 * Sets the Interface Identifier. 875 * 876 * @param[in] aIid An Interface Identifier. 877 */ SetIid(const InterfaceIdentifier & aIid)878 void SetIid(const InterfaceIdentifier &aIid) { GetIid() = aIid; } 879 880 /** 881 * Returns the IPv6 address scope. 882 * 883 * @returns The IPv6 address scope. 884 */ 885 uint8_t GetScope(void) const; 886 887 /** 888 * Returns the number of IPv6 prefix bits that match. 889 * 890 * @param[in] aOther The IPv6 address to match against. 891 * 892 * @returns The number of IPv6 prefix bits that match. 893 */ 894 uint8_t PrefixMatch(const Address &aOther) const; 895 896 /** 897 * Indicates whether address matches a given type filter. 898 * 899 * @param[in] aFilter An address type filter. 900 * 901 * @retval TRUE The address matches @p aFilter. 902 * @retval FALSE The address does not match @p aFilter. 903 */ 904 bool MatchesFilter(TypeFilter aFilter) const; 905 906 /** 907 * Sets the IPv6 address by performing NAT64 address translation from a given IPv4 address as specified 908 * in RFC 6052. 909 * 910 * The NAT64 @p aPrefix MUST have one of the following lengths: 32, 40, 48, 56, 64, or 96, otherwise the behavior 911 * of this method is undefined. 912 * 913 * @param[in] aPrefix The prefix to use for IPv4/IPv6 translation. 914 * @param[in] aIp4Address The IPv4 address to translate to IPv6. 915 */ 916 void SynthesizeFromIp4Address(const Prefix &aPrefix, const Ip4::Address &aIp4Address); 917 918 /** 919 * Converts an IPv6 address string to binary. 920 * 921 * @param[in] aString A pointer to the null-terminated string. 922 * 923 * @retval kErrorNone Successfully parsed the IPv6 address string. 924 * @retval kErrorParse Failed to parse the IPv6 address string. 925 */ 926 Error FromString(const char *aString); 927 928 /** 929 * Converts the IPv6 address to a string. 930 * 931 * The IPv6 address string is formatted as 16 hex values separated by ':' (i.e., "%x:%x:%x:...:%x"). 932 * 933 * @returns An `InfoString` representing the IPv6 address. 934 */ 935 InfoString ToString(void) const; 936 937 /** 938 * Convert the IPv6 address to a C string. 939 * 940 * The IPv6 address string is formatted as 16 hex values separated by ':' (i.e., "%x:%x:%x:...:%x"). 941 * 942 * If the resulting string does not fit in @p aBuffer (within its @p aSize characters), the string will be 943 * truncated but the outputted string is always null-terminated. 944 * 945 * @param[out] aBuffer A pointer to a char array to output the string (MUST NOT be `nullptr`). 946 * @param[in] aSize The size of @p aBuffer (in bytes). 947 */ 948 void ToString(char *aBuffer, uint16_t aSize) const; 949 950 /** 951 * Overloads operator `<` to compare two IPv6 addresses. 952 * 953 * @param[in] aOther The other IPv6 address to compare with. 954 * 955 * @retval true The IPv6 address is smaller than @p aOther. 956 * @retval false The IPv6 address is larger than or equal to @p aOther. 957 */ operator <(const Address & aOther) const958 bool operator<(const Address &aOther) const { return memcmp(mFields.m8, aOther.mFields.m8, sizeof(Address)) < 0; } 959 960 private: 961 static constexpr uint8_t kMulticastNetworkPrefixLengthOffset = 3; // Prefix-Based Multicast Address (RFC3306) 962 static constexpr uint8_t kMulticastNetworkPrefixOffset = 4; // Prefix-Based Multicast Address (RFC3306) 963 964 void SetToLocator(const NetworkPrefix &aNetworkPrefix, uint16_t aLocator); 965 void ToString(StringWriter &aWriter) const; 966 void AppendHexWords(StringWriter &aWriter, uint8_t aLength) const; 967 968 static const Address &GetLinkLocalAllNodesMulticast(void); 969 static const Address &GetLinkLocalAllRoutersMulticast(void); 970 static const Address &GetRealmLocalAllNodesMulticast(void); 971 static const Address &GetRealmLocalAllRoutersMulticast(void); 972 static const Address &GetRealmLocalAllMplForwarders(void); 973 974 static void CopyBits(uint8_t *aDst, const uint8_t *aSrc, uint8_t aNumBits); 975 976 Error ParseFrom(const char *aString, char aTerminatorChar); 977 978 } OT_TOOL_PACKED_END; 979 980 /** 981 * @} 982 */ 983 984 } // namespace Ip6 985 986 DefineCoreType(otIp6NetworkPrefix, Ip6::NetworkPrefix); 987 DefineCoreType(otIp6Prefix, Ip6::Prefix); 988 DefineCoreType(otIp6InterfaceIdentifier, Ip6::InterfaceIdentifier); 989 DefineCoreType(otIp6Address, Ip6::Address); 990 991 } // namespace ot 992 993 #endif // IP6_ADDRESS_HPP_ 994