/* * Copyright (c) 2017, The OpenThread Authors. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holder nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /** * @file * This file includes definition for data types used by Thread border agent. */ #ifndef OTBR_COMMON_TYPES_HPP_ #define OTBR_COMMON_TYPES_HPP_ #include "openthread-br/config.h" #include #include #include #include #include #include #include #include "common/byteswap.hpp" #ifndef IN6ADDR_ANY /** * Any IPv6 address literal. */ #define IN6ADDR_ANY "::" #endif #define OTBR_IP6_ADDRESS_SIZE 16 #define OTBR_IP6_PREFIX_SIZE 8 #define OTBR_IP4_ADDRESS_SIZE 4 #define OTBR_NETWORK_KEY_SIZE 16 #define OTBR_PSKC_SIZE 16 /** * Forward declaration for otIp6Prefix to avoid including */ struct otIp6Prefix; /** * This enumeration represents error codes used throughout OpenThread Border Router. */ enum otbrError { OTBR_ERROR_NONE = 0, ///< No error. OTBR_ERROR_ERRNO = -1, ///< Error defined by errno. OTBR_ERROR_DBUS = -2, ///< DBus error. OTBR_ERROR_MDNS = -3, ///< mDNS error. OTBR_ERROR_OPENTHREAD = -4, ///< OpenThread error. OTBR_ERROR_REST = -5, ///< Rest Server error. OTBR_ERROR_SMCROUTE = -6, ///< SMCRoute error. OTBR_ERROR_NOT_FOUND = -7, ///< Not found. OTBR_ERROR_PARSE = -8, ///< Parse error. OTBR_ERROR_NOT_IMPLEMENTED = -9, ///< Not implemented error. OTBR_ERROR_INVALID_ARGS = -10, ///< Invalid arguments error. OTBR_ERROR_DUPLICATED = -11, ///< Duplicated operation, resource or name. OTBR_ERROR_ABORTED = -12, ///< The operation is aborted. OTBR_ERROR_INVALID_STATE = -13, ///< The target isn't in a valid state. OTBR_ERROR_INFRA_LINK_CHANGED = -14, ///< The infrastructure link is changed. OTBR_ERROR_DROPPED = -15, ///< The packet is dropped. }; namespace otbr { enum { kSizePSKc = 16, ///< Size of PSKc. kSizeNetworkName = 16, ///< Max size of Network Name. kSizeExtPanId = 8, ///< Size of Extended PAN ID. kSizeEui64 = 8, ///< Size of Eui64. kSizeExtAddr = kSizeEui64, ///< Size of Extended Address. }; static constexpr char kSolicitedMulticastAddressPrefix[] = "ff02::01:ff00:0"; static constexpr char kLinkLocalAllNodesMulticastAddress[] = "ff02::01"; /** * This class implements the Ipv6 address functionality. */ class Ip6Address { public: /** * Default constructor. */ Ip6Address(void) { m64[0] = 0; m64[1] = 0; } /** * Constructor with an 16-bit Thread locator. * * @param[in] aLocator The 16-bit Thread locator, RLOC or ALOC. */ Ip6Address(uint16_t aLocator) { m64[0] = 0; m32[2] = 0; m16[6] = 0; m8[14] = aLocator >> 8; m8[15] = aLocator & 0xff; } /** * Constructor with an Ip6 address. * * @param[in] aAddress The Ip6 address. */ Ip6Address(const uint8_t (&aAddress)[16]); /** * Constructor with an otIp6Address. * * @param[in] aAddress A const reference to an otIp6Address. */ explicit Ip6Address(const otIp6Address &aAddress); /** * Constructor with a string. * * @param[in] aString The string representing the IPv6 address. */ Ip6Address(const char *aString) { FromString(aString, *this); } /** * This method overloads `<` operator and compares if the Ip6 address is smaller than the other address. * * @param[in] aOther The other Ip6 address to compare with. * * @returns Whether the Ip6 address is smaller than the other address. */ bool operator<(const Ip6Address &aOther) const { return memcmp(this, &aOther, sizeof(Ip6Address)) < 0; } /** * This method overloads `==` operator and compares if the Ip6 address is equal to the other address. * * @param[in] aOther The other Ip6 address to compare with. * * @returns Whether the Ip6 address is equal to the other address. */ bool operator==(const Ip6Address &aOther) const { return m64[0] == aOther.m64[0] && m64[1] == aOther.m64[1]; } /** * This method overloads `!=` operator and compares if the Ip6 address is NOT equal to the other address. * * @param[in] aOther The other Ip6 address to compare with. * * @returns Whether the Ip6 address is NOT equal to the other address. */ bool operator!=(const Ip6Address &aOther) const { return !(*this == aOther); } /** * Retrieve the 16-bit Thread locator. * * @returns RLOC16 or ALOC16. */ uint16_t ToLocator(void) const { return static_cast(m8[14] << 8 | m8[15]); } /** * This method returns the solicited node multicast address. * * @returns The solicited node multicast address. */ Ip6Address ToSolicitedNodeMulticastAddress(void) const; /** * This method returns the string representation for the Ip6 address. * * @returns The string representation of the Ip6 address. */ std::string ToString(void) const; /** * This method indicates whether or not the Ip6 address is the Unspecified Address. * * @retval TRUE If the Ip6 address is the Unspecified Address. * @retval FALSE If the Ip6 address is not the Unspecified Address. */ bool IsUnspecified(void) const { return m64[0] == 0 && m64[1] == 0; } /** * This method returns if the Ip6 address is a multicast address. * * @returns Whether the Ip6 address is a multicast address. */ bool IsMulticast(void) const { return m8[0] == 0xff; } /** * This method returns if the Ip6 address is a link-local address. * * @returns Whether the Ip6 address is a link-local address. */ bool IsLinkLocal(void) const { return (m16[0] & bswap_16(0xffc0)) == bswap_16(0xfe80); } /** * This method returns whether or not the Ip6 address is the Loopback Address. * * @retval TRUE If the Ip6 address is the Loopback Address. * @retval FALSE If the Ip6 address is not the Loopback Address. */ bool IsLoopback(void) const { return (m32[0] == 0 && m32[1] == 0 && m32[2] == 0 && m32[3] == htobe32(1)); } /** * This function returns the wellknown Link Local All Nodes Multicast Address (ff02::1). * * @returns The Link Local All Nodes Multicast Address. */ static const Ip6Address &GetLinkLocalAllNodesMulticastAddress(void) { static Ip6Address sLinkLocalAllNodesMulticastAddress = FromString(kLinkLocalAllNodesMulticastAddress); return sLinkLocalAllNodesMulticastAddress; } /** * This function returns the wellknown Solicited Node Multicast Address Prefix (ff02::01:ff00:0). * * @returns The Solicited Node Multicast Address Prefix. */ static const Ip6Address &GetSolicitedMulticastAddressPrefix(void) { static Ip6Address sSolicitedMulticastAddressPrefix = FromString(kSolicitedMulticastAddressPrefix); return sSolicitedMulticastAddressPrefix; } /** * This function converts Ip6 addresses from text to `Ip6Address`. * * @param[in] aStr The Ip6 address text. * @param[out] aAddr A reference to `Ip6Address` to output the Ip6 address. * * @retval OTBR_ERROR_NONE If the Ip6 address was successfully converted. * @retval OTBR_ERROR_INVALID_ARGS If @p `aStr` is not a valid string representing of Ip6 address. */ static otbrError FromString(const char *aStr, Ip6Address &aAddr); /** * This method copies the Ip6 address to a `sockaddr_in6` structure. * * @param[out] aSockAddr The `sockaddr_in6` structure to copy the Ip6 address to. */ void CopyTo(struct sockaddr_in6 &aSockAddr) const; /** * This method copies the Ip6 address from a `sockaddr_in6` structure. * * @param[in] aSockAddr The `sockaddr_in6` structure to copy the Ip6 address from. */ void CopyFrom(const struct sockaddr_in6 &aSockAddr); /** * This method copies the Ip6 address to a `in6_addr` structure. * * @param[out] aIn6Addr The `in6_addr` structure to copy the Ip6 address to. */ void CopyTo(struct in6_addr &aIn6Addr) const; /** * This method copies the Ip6 address from a `in6_addr` structure. * * @param[in] aIn6Addr The `in6_addr` structure to copy the Ip6 address from. */ void CopyFrom(const struct in6_addr &aIn6Addr); union { uint8_t m8[16]; uint16_t m16[8]; uint32_t m32[4]; uint64_t m64[2]; }; private: static Ip6Address FromString(const char *aStr); }; /** * This class represents a Ipv6 prefix. */ class Ip6Prefix { public: /** * Default constructor. */ Ip6Prefix(void) { Clear(); } /** * Constructor with an Ip6 address string and prefix length. * * @param[in] aIp6AddrStr The IPv6 address string. * @param[in] aLength The prefix length. */ Ip6Prefix(const char *aIp6AddrStr, uint8_t aLength) : mPrefix(aIp6AddrStr) , mLength(aLength) { } /** * This method overloads `==` operator for comparing two Ip6Prefix objects by comparing their prefix and length. * * Two IpPrefix objects are considered equal if: * - their lengths are equal, and * - their first n-bits of the addresses are the same, where n is the length of the prefix. * * @param[in] aOther The Ip6Prefix object to compare with. * * @returns True if the two objects are equal, false otherwise. */ bool operator==(const Ip6Prefix &aOther) const; /** * This method overloads `!=` operator for comparing two Ip6Prefix objects. * @param[in] aOther The Ip6Prefix object to compare with. * * @returns True if the two objects are NOT equal, false otherwise. */ bool operator!=(const Ip6Prefix &aOther) const; /** * This method sets the Ip6 prefix to an `otIp6Prefix` value. * * @param[in] aPrefix The `otIp6Prefix` value to set the Ip6 prefix. */ void Set(const otIp6Prefix &aPrefix); /** * This method returns the string representation for the Ip6 prefix. * * @returns The string representation of the Ip6 prefix. */ std::string ToString(void) const; /** * This method clears the Ip6 prefix to be unspecified. */ void Clear(void) { memset(reinterpret_cast(this), 0, sizeof(*this)); } /** * This method returns if the Ip6 prefix is valid. * * @returns If the Ip6 prefix is valid. */ bool IsValid(void) const { return mLength > 0 && mLength <= 128; } /** * This method checks if the object is the default route prefix ("::/0") * * @returns true if the object is the default route prefix, false otherwise. */ bool IsDefaultRoutePrefix(void) const { return (*this == Ip6Prefix("::", 0)); } /** * This method checks if the object is the ULA prefix ("fc00::/7") * * @returns true if the object is the ULA prefix, false otherwise. */ bool IsUlaPrefix(void) const { return (*this == Ip6Prefix("fc00::", 7)); } Ip6Address mPrefix; ///< The IPv6 prefix. uint8_t mLength; ///< The IPv6 prefix length (in bits). }; /** * This class represents a Ipv6 address and its info. */ class Ip6AddressInfo { public: Ip6AddressInfo(void) { Clear(); } Ip6AddressInfo(const otIp6Address &aAddress, uint8_t aPrefixLength, uint8_t aScope, bool aPreferred, bool aMeshLocal) : mAddress(aAddress) , mPrefixLength(aPrefixLength) , mScope(aScope) , mPreferred(aPreferred) , mMeshLocal(aMeshLocal) { } void Clear(void) { memset(reinterpret_cast(this), 0, sizeof(*this)); } otIp6Address mAddress; uint8_t mPrefixLength; uint8_t mScope : 4; bool mPreferred : 1; bool mMeshLocal : 1; bool operator==(const Ip6AddressInfo &aOther) const { return memcmp(this, &aOther, sizeof(Ip6AddressInfo)) == 0; } }; /** * This class represents an ethernet MAC address. */ class MacAddress { public: /** * Default constructor. */ MacAddress(void) { m16[0] = 0; m16[1] = 0; m16[2] = 0; } /** * This method returns the string representation for the MAC address. * * @returns The string representation of the MAC address. */ std::string ToString(void) const; union { uint8_t m8[6]; uint16_t m16[3]; }; }; struct MdnsResponseCounters { uint32_t mSuccess; ///< The number of successful responses uint32_t mNotFound; ///< The number of 'not found' responses uint32_t mInvalidArgs; ///< The number of 'invalid arg' responses uint32_t mDuplicated; ///< The number of 'duplicated' responses uint32_t mNotImplemented; ///< The number of 'not implemented' responses uint32_t mUnknownError; ///< The number of unknown error responses uint32_t mAborted; ///< The number of aborted responses uint32_t mInvalidState; ///< The number of 'invalid state' responses }; struct MdnsTelemetryInfo { static constexpr uint32_t kEmaFactorNumerator = 1; static constexpr uint32_t kEmaFactorDenominator = 2; static_assert(kEmaFactorNumerator > 0, "kEmaFactorNumerator must be greater than 0"); static_assert(kEmaFactorDenominator > kEmaFactorNumerator, "kEmaFactorDenominator must be greater than kEmaFactorNumerator"); MdnsResponseCounters mHostRegistrations; MdnsResponseCounters mKeyRegistrations; MdnsResponseCounters mServiceRegistrations; MdnsResponseCounters mHostResolutions; MdnsResponseCounters mServiceResolutions; uint32_t mHostRegistrationEmaLatency; ///< The EMA latency of host registrations in milliseconds uint32_t mKeyRegistrationEmaLatency; ///< The EMA latency of key registrations in milliseconds uint32_t mServiceRegistrationEmaLatency; ///< The EMA latency of service registrations in milliseconds uint32_t mHostResolutionEmaLatency; ///< The EMA latency of host resolutions in milliseconds uint32_t mServiceResolutionEmaLatency; ///< The EMA latency of service resolutions in milliseconds }; static constexpr size_t kVendorOuiLength = 3; static constexpr size_t kMaxVendorNameLength = 24; static constexpr size_t kMaxProductNameLength = 24; /** * This method converts a otbrError to a otError. * * @param[in] aError a otbrError code. * * @returns a otError code. */ otError OtbrErrorToOtError(otbrError aError); } // namespace otbr #endif // OTBR_COMMON_TYPES_HPP_