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