xref: /aosp_15_r20/external/ot-br-posix/src/common/types.hpp (revision 4a64e381480ef79f0532b2421e44e6ee336b8e0d)
1 /*
2  *    Copyright (c) 2017, 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 definition for data types used by Thread border agent.
32  */
33 
34 #ifndef OTBR_COMMON_TYPES_HPP_
35 #define OTBR_COMMON_TYPES_HPP_
36 
37 #include "openthread-br/config.h"
38 
39 #include <netinet/in.h>
40 #include <stdint.h>
41 #include <string.h>
42 #include <string>
43 #include <vector>
44 
45 #include <openthread/error.h>
46 #include <openthread/ip6.h>
47 
48 #include "common/byteswap.hpp"
49 
50 #ifndef IN6ADDR_ANY
51 /**
52  * Any IPv6 address literal.
53  */
54 #define IN6ADDR_ANY "::"
55 #endif
56 
57 #define OTBR_IP6_ADDRESS_SIZE 16
58 #define OTBR_IP6_PREFIX_SIZE 8
59 #define OTBR_IP4_ADDRESS_SIZE 4
60 #define OTBR_NETWORK_KEY_SIZE 16
61 #define OTBR_PSKC_SIZE 16
62 
63 /**
64  * Forward declaration for otIp6Prefix to avoid including <openthread/ip6.h>
65  */
66 struct otIp6Prefix;
67 
68 /**
69  * This enumeration represents error codes used throughout OpenThread Border Router.
70  */
71 enum otbrError
72 {
73     OTBR_ERROR_NONE = 0, ///< No error.
74 
75     OTBR_ERROR_ERRNO              = -1,  ///< Error defined by errno.
76     OTBR_ERROR_DBUS               = -2,  ///< DBus error.
77     OTBR_ERROR_MDNS               = -3,  ///< mDNS error.
78     OTBR_ERROR_OPENTHREAD         = -4,  ///< OpenThread error.
79     OTBR_ERROR_REST               = -5,  ///< Rest Server error.
80     OTBR_ERROR_SMCROUTE           = -6,  ///< SMCRoute error.
81     OTBR_ERROR_NOT_FOUND          = -7,  ///< Not found.
82     OTBR_ERROR_PARSE              = -8,  ///< Parse error.
83     OTBR_ERROR_NOT_IMPLEMENTED    = -9,  ///< Not implemented error.
84     OTBR_ERROR_INVALID_ARGS       = -10, ///< Invalid arguments error.
85     OTBR_ERROR_DUPLICATED         = -11, ///< Duplicated operation, resource or name.
86     OTBR_ERROR_ABORTED            = -12, ///< The operation is aborted.
87     OTBR_ERROR_INVALID_STATE      = -13, ///< The target isn't in a valid state.
88     OTBR_ERROR_INFRA_LINK_CHANGED = -14, ///< The infrastructure link is changed.
89     OTBR_ERROR_DROPPED            = -15, ///< The packet is dropped.
90 };
91 
92 namespace otbr {
93 
94 enum
95 {
96     kSizePSKc        = 16,         ///< Size of PSKc.
97     kSizeNetworkName = 16,         ///< Max size of Network Name.
98     kSizeExtPanId    = 8,          ///< Size of Extended PAN ID.
99     kSizeEui64       = 8,          ///< Size of Eui64.
100     kSizeExtAddr     = kSizeEui64, ///< Size of Extended Address.
101 };
102 
103 static constexpr char kSolicitedMulticastAddressPrefix[]   = "ff02::01:ff00:0";
104 static constexpr char kLinkLocalAllNodesMulticastAddress[] = "ff02::01";
105 
106 /**
107  * This class implements the Ipv6 address functionality.
108  */
109 class Ip6Address
110 {
111 public:
112     /**
113      * Default constructor.
114      */
Ip6Address(void)115     Ip6Address(void)
116     {
117         m64[0] = 0;
118         m64[1] = 0;
119     }
120 
121     /**
122      * Constructor with an 16-bit Thread locator.
123      *
124      * @param[in] aLocator  The 16-bit Thread locator, RLOC or ALOC.
125      */
Ip6Address(uint16_t aLocator)126     Ip6Address(uint16_t aLocator)
127     {
128         m64[0] = 0;
129         m32[2] = 0;
130         m16[6] = 0;
131         m8[14] = aLocator >> 8;
132         m8[15] = aLocator & 0xff;
133     }
134 
135     /**
136      * Constructor with an Ip6 address.
137      *
138      * @param[in] aAddress  The Ip6 address.
139      */
140     Ip6Address(const uint8_t (&aAddress)[16]);
141 
142     /**
143      * Constructor with an otIp6Address.
144      *
145      * @param[in] aAddress  A const reference to an otIp6Address.
146      */
147     explicit Ip6Address(const otIp6Address &aAddress);
148 
149     /**
150      * Constructor with a string.
151      *
152      * @param[in] aString The string representing the IPv6 address.
153      */
Ip6Address(const char * aString)154     Ip6Address(const char *aString) { FromString(aString, *this); }
155 
156     /**
157      * This method overloads `<` operator and compares if the Ip6 address is smaller than the other address.
158      *
159      * @param[in] aOther  The other Ip6 address to compare with.
160      *
161      * @returns Whether the Ip6 address is smaller than the other address.
162      */
operator <(const Ip6Address & aOther) const163     bool operator<(const Ip6Address &aOther) const { return memcmp(this, &aOther, sizeof(Ip6Address)) < 0; }
164 
165     /**
166      * This method overloads `==` operator and compares if the Ip6 address is equal to the other address.
167      *
168      * @param[in] aOther  The other Ip6 address to compare with.
169      *
170      * @returns Whether the Ip6 address is equal to the other address.
171      */
operator ==(const Ip6Address & aOther) const172     bool operator==(const Ip6Address &aOther) const { return m64[0] == aOther.m64[0] && m64[1] == aOther.m64[1]; }
173 
174     /**
175      * This method overloads `!=` operator and compares if the Ip6 address is NOT equal to the other address.
176      *
177      * @param[in] aOther  The other Ip6 address to compare with.
178      *
179      * @returns Whether the Ip6 address is NOT equal to the other address.
180      */
operator !=(const Ip6Address & aOther) const181     bool operator!=(const Ip6Address &aOther) const { return !(*this == aOther); }
182 
183     /**
184      * Retrieve the 16-bit Thread locator.
185      *
186      * @returns RLOC16 or ALOC16.
187      */
ToLocator(void) const188     uint16_t ToLocator(void) const { return static_cast<uint16_t>(m8[14] << 8 | m8[15]); }
189 
190     /**
191      * This method returns the solicited node multicast address.
192      *
193      * @returns The solicited node multicast address.
194      */
195     Ip6Address ToSolicitedNodeMulticastAddress(void) const;
196 
197     /**
198      * This method returns the string representation for the Ip6 address.
199      *
200      * @returns The string representation of the Ip6 address.
201      */
202     std::string ToString(void) const;
203 
204     /**
205      * This method indicates whether or not the Ip6 address is the Unspecified Address.
206      *
207      * @retval TRUE   If the Ip6 address is the Unspecified Address.
208      * @retval FALSE  If the Ip6 address is not the Unspecified Address.
209      */
IsUnspecified(void) const210     bool IsUnspecified(void) const { return m64[0] == 0 && m64[1] == 0; }
211 
212     /**
213      * This method returns if the Ip6 address is a multicast address.
214      *
215      * @returns Whether the Ip6 address is a multicast address.
216      */
IsMulticast(void) const217     bool IsMulticast(void) const { return m8[0] == 0xff; }
218 
219     /**
220      * This method returns if the Ip6 address is a link-local address.
221      *
222      * @returns Whether the Ip6 address is a link-local address.
223      */
IsLinkLocal(void) const224     bool IsLinkLocal(void) const { return (m16[0] & bswap_16(0xffc0)) == bswap_16(0xfe80); }
225 
226     /**
227      * This method returns whether or not the Ip6 address is the Loopback Address.
228      *
229      * @retval TRUE   If the Ip6 address is the Loopback Address.
230      * @retval FALSE  If the Ip6 address is not the Loopback Address.
231      */
IsLoopback(void) const232     bool IsLoopback(void) const { return (m32[0] == 0 && m32[1] == 0 && m32[2] == 0 && m32[3] == htobe32(1)); }
233 
234     /**
235      * This function returns the wellknown Link Local All Nodes Multicast Address (ff02::1).
236      *
237      * @returns The Link Local All Nodes Multicast Address.
238      */
GetLinkLocalAllNodesMulticastAddress(void)239     static const Ip6Address &GetLinkLocalAllNodesMulticastAddress(void)
240     {
241         static Ip6Address sLinkLocalAllNodesMulticastAddress = FromString(kLinkLocalAllNodesMulticastAddress);
242 
243         return sLinkLocalAllNodesMulticastAddress;
244     }
245 
246     /**
247      * This function returns the wellknown Solicited Node Multicast Address Prefix (ff02::01:ff00:0).
248      *
249      * @returns The Solicited Node Multicast Address Prefix.
250      */
GetSolicitedMulticastAddressPrefix(void)251     static const Ip6Address &GetSolicitedMulticastAddressPrefix(void)
252     {
253         static Ip6Address sSolicitedMulticastAddressPrefix = FromString(kSolicitedMulticastAddressPrefix);
254 
255         return sSolicitedMulticastAddressPrefix;
256     }
257 
258     /**
259      * This function converts Ip6 addresses from text to `Ip6Address`.
260      *
261      * @param[in]  aStr   The Ip6 address text.
262      * @param[out] aAddr  A reference to `Ip6Address` to output the Ip6 address.
263      *
264      * @retval OTBR_ERROR_NONE          If the Ip6 address was successfully converted.
265      * @retval OTBR_ERROR_INVALID_ARGS  If @p `aStr` is not a valid string representing of Ip6 address.
266      */
267     static otbrError FromString(const char *aStr, Ip6Address &aAddr);
268 
269     /**
270      * This method copies the Ip6 address to a `sockaddr_in6` structure.
271      *
272      * @param[out] aSockAddr  The `sockaddr_in6` structure to copy the Ip6 address to.
273      */
274     void CopyTo(struct sockaddr_in6 &aSockAddr) const;
275 
276     /**
277      * This method copies the Ip6 address from a `sockaddr_in6` structure.
278      *
279      * @param[in] aSockAddr  The `sockaddr_in6` structure to copy the Ip6 address from.
280      */
281     void CopyFrom(const struct sockaddr_in6 &aSockAddr);
282 
283     /**
284      * This method copies the Ip6 address to a `in6_addr` structure.
285      *
286      * @param[out] aIn6Addr  The `in6_addr` structure to copy the Ip6 address to.
287      */
288     void CopyTo(struct in6_addr &aIn6Addr) const;
289 
290     /**
291      * This method copies the Ip6 address from a `in6_addr` structure.
292      *
293      * @param[in] aIn6Addr  The `in6_addr` structure to copy the Ip6 address from.
294      */
295     void CopyFrom(const struct in6_addr &aIn6Addr);
296 
297     union
298     {
299         uint8_t  m8[16];
300         uint16_t m16[8];
301         uint32_t m32[4];
302         uint64_t m64[2];
303     };
304 
305 private:
306     static Ip6Address FromString(const char *aStr);
307 };
308 
309 /**
310  * This class represents a Ipv6 prefix.
311  */
312 class Ip6Prefix
313 {
314 public:
315     /**
316      * Default constructor.
317      */
Ip6Prefix(void)318     Ip6Prefix(void) { Clear(); }
319 
320     /**
321      * Constructor with an Ip6 address string and prefix length.
322      *
323      * @param[in] aIp6AddrStr The IPv6 address string.
324      * @param[in] aLength     The prefix length.
325      */
Ip6Prefix(const char * aIp6AddrStr,uint8_t aLength)326     Ip6Prefix(const char *aIp6AddrStr, uint8_t aLength)
327         : mPrefix(aIp6AddrStr)
328         , mLength(aLength)
329     {
330     }
331 
332     /**
333      * This method overloads `==` operator for comparing two Ip6Prefix objects by comparing their prefix and length.
334      *
335      * Two IpPrefix objects are considered equal if:
336      *  - their lengths are equal, and
337      *  - their first n-bits of the addresses are the same, where n is the length of the prefix.
338      *
339      * @param[in] aOther The Ip6Prefix object to compare with.
340      *
341      * @returns True if the two objects are equal, false otherwise.
342      */
343     bool operator==(const Ip6Prefix &aOther) const;
344 
345     /**
346      * This method overloads `!=` operator for comparing two Ip6Prefix objects.
347 
348      * @param[in] aOther The Ip6Prefix object to compare with.
349      *
350      * @returns True if the two objects are NOT equal, false otherwise.
351      */
352     bool operator!=(const Ip6Prefix &aOther) const;
353 
354     /**
355      * This method sets the Ip6 prefix to an `otIp6Prefix` value.
356      *
357      * @param[in] aPrefix  The `otIp6Prefix` value to set the Ip6 prefix.
358      */
359     void Set(const otIp6Prefix &aPrefix);
360 
361     /**
362      * This method returns the string representation for the Ip6 prefix.
363      *
364      * @returns The string representation of the Ip6 prefix.
365      */
366     std::string ToString(void) const;
367 
368     /**
369      * This method clears the Ip6 prefix to be unspecified.
370      */
Clear(void)371     void Clear(void) { memset(reinterpret_cast<void *>(this), 0, sizeof(*this)); }
372 
373     /**
374      * This method returns if the Ip6 prefix is valid.
375      *
376      * @returns If the Ip6 prefix is valid.
377      */
IsValid(void) const378     bool IsValid(void) const { return mLength > 0 && mLength <= 128; }
379 
380     /**
381      * This method checks if the object is the default route prefix ("::/0")
382      *
383      * @returns true if the object is the default route prefix, false otherwise.
384      */
IsDefaultRoutePrefix(void) const385     bool IsDefaultRoutePrefix(void) const { return (*this == Ip6Prefix("::", 0)); }
386 
387     /**
388      * This method checks if the object is the ULA prefix ("fc00::/7")
389      *
390      * @returns true if the object is the ULA prefix, false otherwise.
391      */
IsUlaPrefix(void) const392     bool IsUlaPrefix(void) const { return (*this == Ip6Prefix("fc00::", 7)); }
393 
394     Ip6Address mPrefix; ///< The IPv6 prefix.
395     uint8_t    mLength; ///< The IPv6 prefix length (in bits).
396 };
397 
398 /**
399  * This class represents a Ipv6 address and its info.
400  */
401 class Ip6AddressInfo
402 {
403 public:
Ip6AddressInfo(void)404     Ip6AddressInfo(void) { Clear(); }
405 
Ip6AddressInfo(const otIp6Address & aAddress,uint8_t aPrefixLength,uint8_t aScope,bool aPreferred,bool aMeshLocal)406     Ip6AddressInfo(const otIp6Address &aAddress,
407                    uint8_t             aPrefixLength,
408                    uint8_t             aScope,
409                    bool                aPreferred,
410                    bool                aMeshLocal)
411         : mAddress(aAddress)
412         , mPrefixLength(aPrefixLength)
413         , mScope(aScope)
414         , mPreferred(aPreferred)
415         , mMeshLocal(aMeshLocal)
416     {
417     }
418 
Clear(void)419     void Clear(void) { memset(reinterpret_cast<void *>(this), 0, sizeof(*this)); }
420 
421     otIp6Address mAddress;
422     uint8_t      mPrefixLength;
423     uint8_t      mScope : 4;
424     bool         mPreferred : 1;
425     bool         mMeshLocal : 1;
426 
operator ==(const Ip6AddressInfo & aOther) const427     bool operator==(const Ip6AddressInfo &aOther) const { return memcmp(this, &aOther, sizeof(Ip6AddressInfo)) == 0; }
428 };
429 
430 /**
431  * This class represents an ethernet MAC address.
432  */
433 class MacAddress
434 {
435 public:
436     /**
437      * Default constructor.
438      */
MacAddress(void)439     MacAddress(void)
440     {
441         m16[0] = 0;
442         m16[1] = 0;
443         m16[2] = 0;
444     }
445 
446     /**
447      * This method returns the string representation for the MAC address.
448      *
449      * @returns The string representation of the MAC address.
450      */
451     std::string ToString(void) const;
452 
453     union
454     {
455         uint8_t  m8[6];
456         uint16_t m16[3];
457     };
458 };
459 
460 struct MdnsResponseCounters
461 {
462     uint32_t mSuccess;        ///< The number of successful responses
463     uint32_t mNotFound;       ///< The number of 'not found' responses
464     uint32_t mInvalidArgs;    ///< The number of 'invalid arg' responses
465     uint32_t mDuplicated;     ///< The number of 'duplicated' responses
466     uint32_t mNotImplemented; ///< The number of 'not implemented' responses
467     uint32_t mUnknownError;   ///< The number of unknown error responses
468     uint32_t mAborted;        ///< The number of aborted responses
469     uint32_t mInvalidState;   ///< The number of 'invalid state' responses
470 };
471 
472 struct MdnsTelemetryInfo
473 {
474     static constexpr uint32_t kEmaFactorNumerator   = 1;
475     static constexpr uint32_t kEmaFactorDenominator = 2;
476 
477     static_assert(kEmaFactorNumerator > 0, "kEmaFactorNumerator must be greater than 0");
478     static_assert(kEmaFactorDenominator > kEmaFactorNumerator,
479                   "kEmaFactorDenominator must be greater than kEmaFactorNumerator");
480 
481     MdnsResponseCounters mHostRegistrations;
482     MdnsResponseCounters mKeyRegistrations;
483     MdnsResponseCounters mServiceRegistrations;
484     MdnsResponseCounters mHostResolutions;
485     MdnsResponseCounters mServiceResolutions;
486 
487     uint32_t mHostRegistrationEmaLatency;    ///< The EMA latency of host registrations in milliseconds
488     uint32_t mKeyRegistrationEmaLatency;     ///< The EMA latency of key registrations in milliseconds
489     uint32_t mServiceRegistrationEmaLatency; ///< The EMA latency of service registrations in milliseconds
490     uint32_t mHostResolutionEmaLatency;      ///< The EMA latency of host resolutions in milliseconds
491     uint32_t mServiceResolutionEmaLatency;   ///< The EMA latency of service resolutions in milliseconds
492 };
493 
494 static constexpr size_t kVendorOuiLength      = 3;
495 static constexpr size_t kMaxVendorNameLength  = 24;
496 static constexpr size_t kMaxProductNameLength = 24;
497 
498 /**
499  * This method converts a otbrError to a otError.
500  *
501  * @param[in]  aError  a otbrError code.
502  *
503  * @returns  a otError code.
504  */
505 otError OtbrErrorToOtError(otbrError aError);
506 
507 } // namespace otbr
508 
509 #endif // OTBR_COMMON_TYPES_HPP_
510