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