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