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