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