1 /* 2 * Copyright (c) 2020, 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 Neighbor Discovery (ND). 32 * 33 * See RFC 4861 (https://tools.ietf.org/html/rfc4861) and RFC 4191 (https://tools.ietf.org/html/rfc4191). 34 * 35 */ 36 37 #ifndef ND6_HPP_ 38 #define ND6_HPP_ 39 40 #include "openthread-core-config.h" 41 42 #include <stdint.h> 43 44 #include <openthread/netdata.h> 45 #include <openthread/platform/toolchain.h> 46 47 #include "common/const_cast.hpp" 48 #include "common/encoding.hpp" 49 #include "common/equatable.hpp" 50 #include "net/icmp6.hpp" 51 #include "net/ip6.hpp" 52 #include "thread/network_data_types.hpp" 53 54 using ot::Encoding::BigEndian::HostSwap16; 55 using ot::Encoding::BigEndian::HostSwap32; 56 57 namespace ot { 58 namespace Ip6 { 59 namespace Nd { 60 61 typedef NetworkData::RoutePreference RoutePreference; ///< Route Preference 62 63 /** 64 * This class represents the variable length options in Neighbor Discovery messages. 65 * 66 * @sa PrefixInfoOption 67 * @sa RouteInfoOption 68 * 69 */ 70 OT_TOOL_PACKED_BEGIN 71 class Option 72 { 73 friend class RouterAdvertMessage; 74 75 public: 76 enum Type : uint8_t 77 { 78 kTypePrefixInfo = 3, ///< Prefix Information Option. 79 kTypeRouteInfo = 24, ///< Route Information Option. 80 }; 81 82 static constexpr uint16_t kLengthUnit = 8; ///< The unit of length in octets. 83 84 /** 85 * This method gets the option type. 86 * 87 * @returns The option type. 88 * 89 */ GetType(void) const90 uint8_t GetType(void) const { return mType; } 91 92 /** 93 * This method sets the option type. 94 * 95 * @param[in] aType The option type. 96 * 97 * 98 */ SetType(Type aType)99 void SetType(Type aType) { mType = aType; } 100 101 /** 102 * This method sets the length based on a given total option size in bytes. 103 * 104 * Th option must end on a 64-bit boundary, so the length is derived as `(aSize + 7) / 8 * 8`. 105 * 106 * @param[in] aSize The size of option in bytes. 107 * 108 */ SetSize(uint16_t aSize)109 void SetSize(uint16_t aSize) { mLength = static_cast<uint8_t>((aSize + kLengthUnit - 1) / kLengthUnit); } 110 111 /** 112 * This method returns the size of the option in bytes. 113 * 114 * @returns The size of the option in bytes. 115 * 116 */ GetSize(void) const117 uint16_t GetSize(void) const { return mLength * kLengthUnit; } 118 119 /** 120 * This method sets the length of the option (in unit of 8 bytes). 121 * 122 * @param[in] aLength The length of the option in unit of 8 bytes. 123 * 124 */ SetLength(uint8_t aLength)125 void SetLength(uint8_t aLength) { mLength = aLength; } 126 127 /** 128 * This method returns the length of the option (in unit of 8 bytes). 129 * 130 * @returns The length of the option in unit of 8 bytes. 131 * 132 */ GetLength(void) const133 uint16_t GetLength(void) const { return mLength; } 134 135 /** 136 * This method indicates whether or not this option is valid. 137 * 138 * @retval TRUE The option is valid. 139 * @retval FALSE The option is not valid. 140 * 141 */ IsValid(void) const142 bool IsValid(void) const { return mLength > 0; } 143 144 private: 145 class Iterator : public Unequatable<Iterator> 146 { 147 public: 148 Iterator(void); 149 Iterator(const void *aStart, const void *aEnd); 150 operator *(void)151 const Option &operator*(void) { return *mOption; } operator ++(void)152 void operator++(void) { Advance(); } operator ++(int)153 void operator++(int) { Advance(); } operator ==(const Iterator & aOther) const154 bool operator==(const Iterator &aOther) const { return mOption == aOther.mOption; } 155 156 private: 157 static const Option *Next(const Option *aOption); 158 void Advance(void); 159 const Option * Validate(const Option *aOption) const; 160 161 const Option *mOption; 162 const Option *mEnd; 163 }; 164 165 uint8_t mType; // Type of the option. 166 uint8_t mLength; // Length of the option in unit of 8 octets, including the `mType` and `mLength` fields. 167 } OT_TOOL_PACKED_END; 168 169 /** 170 * This class represents the Prefix Information Option. 171 * 172 * See section 4.6.2 of RFC 4861 for definition of this option [https://tools.ietf.org/html/rfc4861#section-4.6.2] 173 * 174 */ 175 OT_TOOL_PACKED_BEGIN 176 class PrefixInfoOption : public Option, private Clearable<PrefixInfoOption> 177 { 178 public: 179 static constexpr Type kType = kTypePrefixInfo; ///< Prefix Information Option Type. 180 181 /** 182 * This method initializes the Prefix Info option with proper type and length and sets all other fields to zero. 183 * 184 */ 185 void Init(void); 186 187 /** 188 * This method indicates whether or not the on-link flag is set. 189 * 190 * @retval TRUE The on-link flag is set. 191 * @retval FALSE The on-link flag is not set. 192 * 193 */ IsOnLinkFlagSet(void) const194 bool IsOnLinkFlagSet(void) const { return (mFlags & kOnLinkFlagMask) != 0; } 195 196 /** 197 * This method sets the on-link (L) flag. 198 * 199 */ SetOnLinkFlag(void)200 void SetOnLinkFlag(void) { mFlags |= kOnLinkFlagMask; } 201 202 /** 203 * This method clears the on-link (L) flag. 204 * 205 */ ClearOnLinkFlag(void)206 void ClearOnLinkFlag(void) { mFlags &= ~kOnLinkFlagMask; } 207 208 /** 209 * This method indicates whether or not the autonomous address-configuration (A) flag is set. 210 * 211 * @retval TRUE The auto address-config flag is set. 212 * @retval FALSE The auto address-config flag is not set. 213 * 214 */ IsAutoAddrConfigFlagSet(void) const215 bool IsAutoAddrConfigFlagSet(void) const { return (mFlags & kAutoConfigFlagMask) != 0; } 216 217 /** 218 * This method sets the autonomous address-configuration (A) flag. 219 * 220 */ SetAutoAddrConfigFlag(void)221 void SetAutoAddrConfigFlag(void) { mFlags |= kAutoConfigFlagMask; } 222 223 /** 224 * This method clears the autonomous address-configuration (A) flag. 225 * 226 */ ClearAutoAddrConfigFlag(void)227 void ClearAutoAddrConfigFlag(void) { mFlags &= ~kAutoConfigFlagMask; } 228 229 /** 230 * This method sets the valid lifetime of the prefix in seconds. 231 * 232 * @param[in] aValidLifetime The valid lifetime in seconds. 233 * 234 */ SetValidLifetime(uint32_t aValidLifetime)235 void SetValidLifetime(uint32_t aValidLifetime) { mValidLifetime = HostSwap32(aValidLifetime); } 236 237 /** 238 * THis method gets the valid lifetime of the prefix in seconds. 239 * 240 * @returns The valid lifetime in seconds. 241 * 242 */ GetValidLifetime(void) const243 uint32_t GetValidLifetime(void) const { return HostSwap32(mValidLifetime); } 244 245 /** 246 * This method sets the preferred lifetime of the prefix in seconds. 247 * 248 * @param[in] aPreferredLifetime The preferred lifetime in seconds. 249 * 250 */ SetPreferredLifetime(uint32_t aPreferredLifetime)251 void SetPreferredLifetime(uint32_t aPreferredLifetime) { mPreferredLifetime = HostSwap32(aPreferredLifetime); } 252 253 /** 254 * THis method returns the preferred lifetime of the prefix in seconds. 255 * 256 * @returns The preferred lifetime in seconds. 257 * 258 */ GetPreferredLifetime(void) const259 uint32_t GetPreferredLifetime(void) const { return HostSwap32(mPreferredLifetime); } 260 261 /** 262 * This method sets the prefix. 263 * 264 * @param[in] aPrefix The prefix contained in this option. 265 * 266 */ 267 void SetPrefix(const Prefix &aPrefix); 268 269 /** 270 * This method gets the prefix in this option. 271 * 272 * @param[out] aPrefix Reference to a `Prefix` to return the prefix. 273 * 274 */ 275 void GetPrefix(Prefix &aPrefix) const; 276 277 /** 278 * This method indicates whether or not the option is valid. 279 * 280 * @retval TRUE The option is valid 281 * @retval FALSE The option is not valid. 282 * 283 */ 284 bool IsValid(void) const; 285 286 PrefixInfoOption(void) = delete; 287 288 private: 289 // Prefix Information Option 290 // 291 // 0 1 2 3 292 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 293 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 294 // | Type | Length | Prefix Length |L|A| Reserved1 | 295 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 296 // | Valid Lifetime | 297 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 298 // | Preferred Lifetime | 299 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 300 // | Reserved2 | 301 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 302 // | | 303 // + + 304 // | | 305 // + Prefix + 306 // | | 307 // + + 308 // | | 309 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 310 311 static constexpr uint8_t kAutoConfigFlagMask = 0x40; // Autonomous address-configuration flag. 312 static constexpr uint8_t kOnLinkFlagMask = 0x80; // On-link flag. 313 314 uint8_t mPrefixLength; // The prefix length in bits. 315 uint8_t mFlags; // The flags field. 316 uint32_t mValidLifetime; // The valid lifetime of the prefix. 317 uint32_t mPreferredLifetime; // The preferred lifetime of the prefix. 318 uint32_t mReserved2; // The reserved field. 319 Address mPrefix; // The prefix. 320 } OT_TOOL_PACKED_END; 321 322 static_assert(sizeof(PrefixInfoOption) == 32, "invalid PrefixInfoOption structure"); 323 324 /** 325 * This class represents the Route Information Option. 326 * 327 * See section 2.3 of RFC 4191 for definition of this option. [https://tools.ietf.org/html/rfc4191#section-2.3] 328 * 329 */ 330 OT_TOOL_PACKED_BEGIN 331 class RouteInfoOption : public Option, private Clearable<RouteInfoOption> 332 { 333 public: 334 static constexpr uint16_t kMinSize = kLengthUnit; ///< Minimum size (in bytes) of a Route Info Option 335 static constexpr Type kType = kTypeRouteInfo; ///< Route Information Option Type. 336 337 /** 338 * This method initializes the option setting the type and clearing (setting to zero) all other fields. 339 * 340 */ 341 void Init(void); 342 343 /** 344 * This method sets the route preference. 345 * 346 * @param[in] aPreference The route preference. 347 * 348 */ 349 void SetPreference(RoutePreference aPreference); 350 351 /** 352 * This method gets the route preference. 353 * 354 * @returns The route preference. 355 * 356 */ 357 RoutePreference GetPreference(void) const; 358 359 /** 360 * This method sets the lifetime of the route in seconds. 361 * 362 * @param[in] aLifetime The lifetime of the route in seconds. 363 * 364 */ SetRouteLifetime(uint32_t aLifetime)365 void SetRouteLifetime(uint32_t aLifetime) { mRouteLifetime = HostSwap32(aLifetime); } 366 367 /** 368 * This method gets Route Lifetime in seconds. 369 * 370 * @returns The Route Lifetime in seconds. 371 * 372 */ GetRouteLifetime(void) const373 uint32_t GetRouteLifetime(void) const { return HostSwap32(mRouteLifetime); } 374 375 /** 376 * This method sets the prefix and adjusts the option length based on the prefix length. 377 * 378 * @param[in] aPrefix The prefix contained in this option. 379 * 380 */ 381 void SetPrefix(const Prefix &aPrefix); 382 383 /** 384 * This method gets the prefix in this option. 385 * 386 * @param[out] aPrefix Reference to a `Prefix` to return the prefix. 387 * 388 */ 389 void GetPrefix(Prefix &aPrefix) const; 390 391 /** 392 * This method tells whether this option is valid. 393 * 394 * @returns A boolean indicates whether this option is valid. 395 * 396 */ 397 bool IsValid(void) const; 398 399 /** 400 * This static method calculates the minimum option length for a given prefix length. 401 * 402 * The option length (which is in unit of 8 octets) can be 1, 2, or 3 depending on the prefix length. It can be 1 403 * for a zero prefix length, 2 if the prefix length is not greater than 64, and 3 otherwise. 404 * 405 * @param[in] aPrefixLength The prefix length (in bits). 406 * 407 * @returns The option length (in unit of 8 octet) for @p aPrefixLength. 408 * 409 */ 410 static uint8_t OptionLengthForPrefix(uint8_t aPrefixLength); 411 412 /** 413 * This static method calculates the minimum option size (in bytes) for a given prefix length. 414 * 415 * @param[in] aPrefixLength The prefix length (in bits). 416 * 417 * @returns The option size (in bytes) for @p aPrefixLength. 418 * 419 */ OptionSizeForPrefix(uint8_t aPrefixLength)420 static uint16_t OptionSizeForPrefix(uint8_t aPrefixLength) 421 { 422 return kLengthUnit * OptionLengthForPrefix(aPrefixLength); 423 } 424 425 RouteInfoOption(void) = delete; 426 427 private: 428 // Route Information Option 429 // 430 // 0 1 2 3 431 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 432 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 433 // | Type | Length | Prefix Length |Resvd|Prf|Resvd| 434 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 435 // | Route Lifetime | 436 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 437 // | Prefix (Variable Length) | 438 // . . 439 // . . 440 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 441 442 static constexpr uint8_t kPreferenceOffset = 3; 443 static constexpr uint8_t kPreferenceMask = 3 << kPreferenceOffset; 444 GetPrefixBytes(void)445 uint8_t * GetPrefixBytes(void) { return AsNonConst(AsConst(this)->GetPrefixBytes()); } GetPrefixBytes(void) const446 const uint8_t *GetPrefixBytes(void) const { return reinterpret_cast<const uint8_t *>(this) + sizeof(*this); } 447 448 uint8_t mPrefixLength; // The prefix length in bits. 449 uint8_t mResvdPrf; // The preference. 450 uint32_t mRouteLifetime; // The lifetime in seconds. 451 // Followed by prefix bytes (variable length). 452 453 } OT_TOOL_PACKED_END; 454 455 static_assert(sizeof(RouteInfoOption) == 8, "invalid RouteInfoOption structure"); 456 457 /** 458 * This class represents a Router Advertisement message. 459 * 460 */ 461 class RouterAdvertMessage 462 { 463 public: 464 /** 465 * This class implements the RA message header. 466 * 467 * See section 2.2 of RFC 4191 [https://datatracker.ietf.org/doc/html/rfc4191] 468 * 469 */ 470 OT_TOOL_PACKED_BEGIN 471 class Header : public Equatable<Header>, private Clearable<Header> 472 { 473 public: 474 /** 475 * This constructor initializes the Router Advertisement message with 476 * zero router lifetime, reachable time and retransmission timer. 477 * 478 */ Header(void)479 Header(void) { SetToDefault(); } 480 481 /** 482 * This method sets the RA message to default values. 483 * 484 */ 485 void SetToDefault(void); 486 487 /** 488 * This method sets the checksum value. 489 * 490 * @param[in] aChecksum The checksum value. 491 * 492 */ SetChecksum(uint16_t aChecksum)493 void SetChecksum(uint16_t aChecksum) { mChecksum = HostSwap16(aChecksum); } 494 495 /** 496 * This method sets the Router Lifetime in seconds. 497 * 498 * @param[in] aRouterLifetime The router lifetime in seconds. 499 * 500 */ SetRouterLifetime(uint16_t aRouterLifetime)501 void SetRouterLifetime(uint16_t aRouterLifetime) { mRouterLifetime = HostSwap16(aRouterLifetime); } 502 503 /** 504 * This method gets the Router Lifetime (in seconds). 505 * 506 * Router Lifetime set to zero indicates that the sender is not a default router. 507 * 508 * @returns The router lifetime in seconds. 509 * 510 */ GetRouterLifetime(void) const511 uint16_t GetRouterLifetime(void) const { return HostSwap16(mRouterLifetime); } 512 513 /** 514 * This method sets the default router preference. 515 * 516 * @param[in] aPreference The router preference. 517 * 518 */ 519 void SetDefaultRouterPreference(RoutePreference aPreference); 520 521 /** 522 * This method gets the default router preference. 523 * 524 * @returns The router preference. 525 * 526 */ 527 RoutePreference GetDefaultRouterPreference(void) const; 528 529 private: 530 // Router Advertisement Message 531 // 532 // 0 1 2 3 533 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 534 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 535 // | Type | Code | Checksum | 536 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 537 // | Cur Hop Limit |M|O|H|Prf|Resvd| Router Lifetime | 538 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 539 // | Reachable Time | 540 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 541 // | Retrans Timer | 542 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 543 // | Options ... 544 // +-+-+-+-+-+-+-+-+-+-+-+- 545 546 static constexpr uint8_t kPreferenceOffset = 3; 547 static constexpr uint8_t kPreferenceMask = 3 << kPreferenceOffset; 548 549 uint8_t mType; 550 uint8_t mCode; 551 uint16_t mChecksum; 552 uint8_t mCurHopLimit; 553 uint8_t mFlags; 554 uint16_t mRouterLifetime; 555 uint32_t mReachableTime; 556 uint32_t mRetransTimer; 557 } OT_TOOL_PACKED_END; 558 559 static_assert(sizeof(Header) == 16, "Invalid RA `Header`"); 560 561 typedef Data<kWithUint16Length> Icmp6Packet; ///< A data buffer containing an ICMPv6 packet. 562 563 /** 564 * This constructor initializes the RA message from a received packet data buffer. 565 * 566 * @param[in] aPacket A received packet data. 567 * 568 */ RouterAdvertMessage(const Icmp6Packet & aPacket)569 explicit RouterAdvertMessage(const Icmp6Packet &aPacket) 570 : mData(aPacket) 571 , mMaxLength(0) 572 { 573 } 574 575 /** 576 * This template constructor initializes the RA message with a given header using a given buffer to store the RA 577 * message. 578 * 579 * @tparam kBufferSize The size of the buffer used to store the RA message. 580 * 581 * @param[in] aHeader The RA message header. 582 * @param[in] aBuffer The data buffer to store the RA message in. 583 * 584 */ 585 template <uint16_t kBufferSize> RouterAdvertMessage(const Header & aHeader,uint8_t (& aBuffer)[kBufferSize])586 RouterAdvertMessage(const Header &aHeader, uint8_t (&aBuffer)[kBufferSize]) 587 : mMaxLength(kBufferSize) 588 { 589 static_assert(kBufferSize >= sizeof(Header), "Buffer for RA msg is too small"); 590 591 memcpy(aBuffer, &aHeader, sizeof(Header)); 592 mData.Init(aBuffer, sizeof(Header)); 593 } 594 595 /** 596 * This method gets the RA message as an `Icmp6Packet`. 597 * 598 * @returns The RA message as an `Icmp6Packet`. 599 * 600 */ GetAsPacket(void) const601 const Icmp6Packet &GetAsPacket(void) const { return mData; } 602 603 /** 604 * This method indicates whether or not the RA message is valid. 605 * 606 * @retval TRUE If the RA message is valid. 607 * @retval FALSE If the RA message is not valid. 608 * 609 */ IsValid(void) const610 bool IsValid(void) const { return (mData.GetBytes() != nullptr) && (mData.GetLength() >= sizeof(Header)); } 611 612 /** 613 * This method gets the RA message's header. 614 * 615 * @returns The RA message's header. 616 * 617 */ GetHeader(void) const618 const Header &GetHeader(void) const { return *reinterpret_cast<const Header *>(mData.GetBytes()); } 619 620 /** 621 * This method appends a Prefix Info Option to the RA message. 622 * 623 * The appended Prefix Info Option will have both on-link (L) and autonomous address-configuration (A) flags set. 624 * 625 * @param[in] aPrefix The prefix. 626 * @param[in] aValidLifetime The valid lifetime in seconds. 627 * @param[in] aPreferredLifetime The preferred lifetime in seconds. 628 * 629 * @retval kErrorNone Option is appended successfully. 630 * @retval kErrorNoBufs No more space in the buffer to append the option. 631 * 632 */ 633 Error AppendPrefixInfoOption(const Prefix &aPrefix, uint32_t aValidLifetime, uint32_t aPreferredLifetime); 634 635 /** 636 * This method appends a Route Info Option to the RA message. 637 * 638 * @param[in] aPrefix The prefix. 639 * @param[in] aRouteLifetime The route lifetime in seconds. 640 * @param[in] aPreference The route preference. 641 * 642 * @retval kErrorNone Option is appended successfully. 643 * @retval kErrorNoBufs No more space in the buffer to append the option. 644 * 645 */ 646 Error AppendRouteInfoOption(const Prefix &aPrefix, uint32_t aRouteLifetime, RoutePreference aPreference); 647 648 /** 649 * This method indicates whether or not the RA message contains any options. 650 * 651 * @retval TRUE If the RA message contains at least one option. 652 * @retval FALSE If the RA message contains no options. 653 * 654 */ ContainsAnyOptions(void) const655 bool ContainsAnyOptions(void) const { return (mData.GetLength() > sizeof(Header)); } 656 657 // The following methods are intended to support range-based `for` 658 // loop iteration over `Option`s in the RA message. 659 begin(void) const660 Option::Iterator begin(void) const { return Option::Iterator(GetOptionStart(), GetDataEnd()); } end(void) const661 Option::Iterator end(void) const { return Option::Iterator(); } 662 663 private: GetOptionStart(void) const664 const uint8_t *GetOptionStart(void) const { return (mData.GetBytes() + sizeof(Header)); } GetDataEnd(void) const665 const uint8_t *GetDataEnd(void) const { return mData.GetBytes() + mData.GetLength(); } 666 Option * AppendOption(uint16_t aOptionSize); 667 668 Data<kWithUint16Length> mData; 669 uint16_t mMaxLength; 670 }; 671 672 /** 673 * This class implements the Router Solicitation message. 674 * 675 * See section 4.1 of RFC 4861 for definition of this message. 676 * https://tools.ietf.org/html/rfc4861#section-4.1 677 * 678 */ 679 OT_TOOL_PACKED_BEGIN 680 class RouterSolicitMessage 681 { 682 public: 683 /** 684 * This constructor initializes the Router Solicitation message. 685 * 686 */ 687 RouterSolicitMessage(void); 688 689 private: 690 Icmp::Header mHeader; // The common ICMPv6 header. 691 } OT_TOOL_PACKED_END; 692 693 static_assert(sizeof(RouterSolicitMessage) == 8, "invalid RouterSolicitMessage structure"); 694 695 } // namespace Nd 696 } // namespace Ip6 697 } // namespace ot 698 699 #endif // ND6_HPP_ 700