• 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 <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