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 DHCPv6 Service. 32 */ 33 34 #ifndef DHCP6_HPP_ 35 #define DHCP6_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include "common/clearable.hpp" 40 #include "common/equatable.hpp" 41 #include "common/message.hpp" 42 #include "common/random.hpp" 43 #include "mac/mac_types.hpp" 44 #include "net/udp6.hpp" 45 46 namespace ot { 47 namespace Dhcp6 { 48 49 using ot::Encoding::BigEndian::HostSwap16; 50 using ot::Encoding::BigEndian::HostSwap32; 51 52 /** 53 * @addtogroup core-dhcp6 54 * 55 * @brief 56 * This module includes definitions for DHCPv6. 57 * 58 * @{ 59 * 60 */ 61 62 constexpr uint16_t kDhcpClientPort = 546; 63 constexpr uint16_t kDhcpServerPort = 547; 64 constexpr uint16_t kHardwareTypeEui64 = 27; 65 constexpr uint16_t kHardwareTypeEthernet = 1; 66 67 /** 68 * DHCPv6 Message Types 69 * 70 */ 71 enum Type : uint8_t 72 { 73 kTypeNone = 0, 74 kTypeSolicit = 1, 75 kTypeAdvertise = 2, 76 kTypeRequest = 3, 77 kTypeConfirm = 4, 78 kTypeRenew = 5, 79 kTypeRebind = 6, 80 kTypeReply = 7, 81 kTypeRelease = 8, 82 kTypeDecline = 9, 83 kTypeReconfigure = 10, 84 kTypeInformationRequest = 11, 85 kTypeRelayForward = 12, 86 kTypeRelayReply = 13, 87 kTypeLeaseQuery = 14, 88 kTypeLeaseQueryReply = 15, 89 }; 90 91 /** 92 * This class represents a DHCP6 transaction identifier. 93 * 94 */ 95 OT_TOOL_PACKED_BEGIN 96 class TransactionId : public Equatable<TransactionId>, public Clearable<TransactionId> 97 { 98 public: 99 static constexpr uint16_t kSize = 3; ///< Transaction Id size (in bytes). 100 101 /** 102 * This method generates a cryptographically secure random sequence to populate the transaction identifier. 103 * 104 * @retval kErrorNone Successfully generated a random transaction identifier. 105 * @retval kErrorFailed Failed to generate random sequence. 106 * 107 */ GenerateRandom(void)108 Error GenerateRandom(void) { return Random::Crypto::FillBuffer(m8, kSize); } 109 110 private: 111 uint8_t m8[kSize]; 112 } OT_TOOL_PACKED_END; 113 114 /** 115 * This class implements DHCPv6 header. 116 * 117 */ 118 OT_TOOL_PACKED_BEGIN 119 class Header : public Clearable<Header> 120 { 121 public: 122 /** 123 * This method returns the DHCPv6 message type. 124 * 125 * @returns The DHCPv6 message type. 126 * 127 */ GetType(void) const128 Type GetType(void) const { return mType; } 129 130 /** 131 * This method sets the DHCPv6 message type. 132 * 133 * @param[in] aType The DHCPv6 message type. 134 * 135 */ SetType(Type aType)136 void SetType(Type aType) { mType = aType; } 137 138 /** 139 * This method returns the DHCPv6 message transaction identifier. 140 * 141 * @returns The DHCPv6 message transaction identifier. 142 * 143 */ GetTransactionId(void) const144 const TransactionId &GetTransactionId(void) const { return mTransactionId; } 145 146 /** 147 * This method sets the DHCPv6 message transaction identifier. 148 * 149 * @param[in] aTransactionId The DHCPv6 message transaction identifier. 150 * 151 */ SetTransactionId(const TransactionId & aTransactionId)152 void SetTransactionId(const TransactionId &aTransactionId) { mTransactionId = aTransactionId; } 153 154 private: 155 Type mType; 156 TransactionId mTransactionId; 157 } OT_TOOL_PACKED_END; 158 159 /** 160 * DHCPv6 Option Codes. 161 * 162 */ 163 enum Code : uint16_t 164 { 165 kOptionClientIdentifier = 1, 166 kOptionServerIdentifier = 2, 167 kOptionIaNa = 3, 168 kOptionIaTa = 4, 169 kOptionIaAddress = 5, 170 kOptionRequestOption = 6, 171 kOptionPreference = 7, 172 kOptionElapsedTime = 8, 173 kOptionRelayMessage = 9, 174 kOptionAuthentication = 11, 175 kOptionServerUnicast = 12, 176 kOptionStatusCode = 13, 177 kOptionRapidCommit = 14, 178 kOptionUserClass = 15, 179 kOptionVendorClass = 16, 180 kOptionVendorSpecificInformation = 17, 181 kOptionInterfaceId = 18, 182 kOptionReconfigureMessage = 19, 183 kOptionReconfigureAccept = 20, 184 kOptionLeaseQuery = 44, 185 kOptionClientData = 45, 186 kOptionClientLastTransactionTime = 46, 187 }; 188 189 /** 190 * This class implements DHCPv6 option. 191 * 192 */ 193 OT_TOOL_PACKED_BEGIN 194 class Option 195 { 196 public: 197 /** 198 * This method initializes the DHCPv6 option to all zeros. 199 * 200 */ Init(void)201 void Init(void) 202 { 203 mCode = 0; 204 mLength = 0; 205 } 206 207 /** 208 * This method returns the DHCPv6 option code. 209 * 210 * @returns The DHCPv6 option code. 211 * 212 */ GetCode(void) const213 Code GetCode(void) const { return static_cast<Code>(HostSwap16(mCode)); } 214 215 /** 216 * This method sets the DHCPv6 option code. 217 * 218 * @param[in] aCode The DHCPv6 option code. 219 * 220 */ SetCode(Code aCode)221 void SetCode(Code aCode) { mCode = HostSwap16(static_cast<uint16_t>(aCode)); } 222 223 /** 224 * This method returns the length of DHCPv6 option. 225 * 226 * @returns The length of DHCPv6 option. 227 * 228 */ GetLength(void) const229 uint16_t GetLength(void) const { return HostSwap16(mLength); } 230 231 /** 232 * This method sets the length of DHCPv6 option. 233 * 234 * @param[in] aLength The length of DHCPv6 option. 235 * 236 */ SetLength(uint16_t aLength)237 void SetLength(uint16_t aLength) { mLength = HostSwap16(aLength); } 238 239 private: 240 uint16_t mCode; 241 uint16_t mLength; 242 } OT_TOOL_PACKED_END; 243 244 /** 245 * DHCP6 Unique Identifier (DUID) Type. 246 * 247 */ 248 enum DuidType : uint16_t 249 { 250 kDuidLinkLayerAddressPlusTime = 1, ///< Link-layer address plus time (DUID-LLT). 251 kDuidEnterpriseNumber = 2, ///< Vendor-assigned unique ID based on Enterprise Number (DUID-EN). 252 kDuidLinkLayerAddress = 3, ///< Link-layer address (DUID-LL). 253 }; 254 255 OT_TOOL_PACKED_BEGIN 256 class ClientIdentifier : public Option 257 { 258 public: 259 /** 260 * This method initializes the DHCPv6 Option. 261 * 262 */ Init(void)263 void Init(void) 264 { 265 SetCode(kOptionClientIdentifier); 266 SetLength(sizeof(*this) - sizeof(Option)); 267 } 268 269 /** 270 * This method returns the client DUID Type. 271 * 272 * @returns The client DUID Type. 273 * 274 */ GetDuidType(void) const275 DuidType GetDuidType(void) const { return static_cast<DuidType>(HostSwap16(mDuidType)); } 276 277 /** 278 * This method sets the client DUID Type. 279 * 280 * @param[in] aDuidType The client DUID Type. 281 * 282 */ SetDuidType(DuidType aDuidType)283 void SetDuidType(DuidType aDuidType) { mDuidType = HostSwap16(static_cast<uint16_t>(aDuidType)); } 284 285 /** 286 * This method returns the client Duid HardwareType. 287 * 288 * @returns The client Duid HardwareType. 289 * 290 */ GetDuidHardwareType(void) const291 uint16_t GetDuidHardwareType(void) const { return HostSwap16(mDuidHardwareType); } 292 293 /** 294 * This method sets the client Duid HardwareType. 295 * 296 * @param[in] aDuidHardwareType The client Duid HardwareType. 297 * 298 */ SetDuidHardwareType(uint16_t aDuidHardwareType)299 void SetDuidHardwareType(uint16_t aDuidHardwareType) { mDuidHardwareType = HostSwap16(aDuidHardwareType); } 300 301 /** 302 * This method returns the client LinkLayerAddress. 303 * 304 * @returns The link-layer address. 305 * 306 */ GetDuidLinkLayerAddress(void) const307 const Mac::ExtAddress &GetDuidLinkLayerAddress(void) const { return mDuidLinkLayerAddress; } 308 309 /** 310 * This method sets the client LinkLayerAddress. 311 * 312 * @param[in] aLinkLayerAddress The client LinkLayerAddress. 313 * 314 */ SetDuidLinkLayerAddress(const Mac::ExtAddress & aDuidLinkLayerAddress)315 void SetDuidLinkLayerAddress(const Mac::ExtAddress &aDuidLinkLayerAddress) 316 { 317 mDuidLinkLayerAddress = aDuidLinkLayerAddress; 318 } 319 320 private: 321 uint16_t mDuidType; 322 uint16_t mDuidHardwareType; 323 Mac::ExtAddress mDuidLinkLayerAddress; 324 } OT_TOOL_PACKED_END; 325 326 OT_TOOL_PACKED_BEGIN 327 class ServerIdentifier : public Option 328 { 329 public: 330 /** 331 * This method initializes the DHCPv6 Option. 332 * 333 */ Init(void)334 void Init(void) 335 { 336 SetCode(kOptionServerIdentifier); 337 SetLength(sizeof(*this) - sizeof(Option)); 338 } 339 340 /** 341 * This method returns the server DUID Type. 342 * 343 * @returns The server DUID Type. 344 * 345 */ GetDuidType(void) const346 DuidType GetDuidType(void) const { return static_cast<DuidType>(HostSwap16(mDuidType)); } 347 348 /** 349 * This method sets the server DUID Type. 350 * 351 * @param[in] aDuidType The server DUID Type. 352 * 353 */ SetDuidType(DuidType aDuidType)354 void SetDuidType(DuidType aDuidType) { mDuidType = HostSwap16(static_cast<uint16_t>(aDuidType)); } 355 356 /** 357 * This method returns the server DUID HardwareType. 358 * 359 * @returns The server DUID HardwareType. 360 * 361 */ GetDuidHardwareType(void) const362 uint16_t GetDuidHardwareType(void) const { return HostSwap16(mDuidHardwareType); } 363 364 /** 365 * This method sets the server DUID HardwareType. 366 * 367 * @param[in] aDuidHardwareType The server DUID HardwareType. 368 * 369 */ SetDuidHardwareType(uint16_t aDuidHardwareType)370 void SetDuidHardwareType(uint16_t aDuidHardwareType) { mDuidHardwareType = HostSwap16(aDuidHardwareType); } 371 372 /** 373 * This method returns the server LinkLayerAddress. 374 * 375 * @returns The link-layer address. 376 * 377 */ GetDuidLinkLayerAddress(void) const378 const Mac::ExtAddress &GetDuidLinkLayerAddress(void) const { return mDuidLinkLayerAddress; } 379 380 /** 381 * This method sets the server LinkLayerAddress. 382 * 383 * @param[in] aLinkLayerAddress The server LinkLayerAddress. 384 * 385 */ SetDuidLinkLayerAddress(const Mac::ExtAddress & aDuidLinkLayerAddress)386 void SetDuidLinkLayerAddress(const Mac::ExtAddress &aDuidLinkLayerAddress) 387 { 388 mDuidLinkLayerAddress = aDuidLinkLayerAddress; 389 } 390 391 private: 392 uint16_t mDuidType; 393 uint16_t mDuidHardwareType; 394 Mac::ExtAddress mDuidLinkLayerAddress; 395 } OT_TOOL_PACKED_END; 396 397 /** 398 * This type represents an Identity Association for Non-temporary Address DHCPv6 option. 399 * 400 */ 401 OT_TOOL_PACKED_BEGIN 402 class IaNa : public Option 403 { 404 public: 405 static constexpr uint32_t kDefaultT1 = 0xffffffffU; ///< Default T1 value. 406 static constexpr uint32_t kDefaultT2 = 0xffffffffU; ///< Default T2 value. 407 408 /** 409 * This method initializes the DHCPv6 Option. 410 * 411 */ Init(void)412 void Init(void) 413 { 414 SetCode(kOptionIaNa); 415 SetLength(sizeof(*this) - sizeof(Option)); 416 } 417 418 /** 419 * This method returns client IAID. 420 * 421 * @returns The client IAID. 422 * 423 */ GetIaid(void) const424 uint32_t GetIaid(void) const { return HostSwap32(mIaid); } 425 426 /** 427 * This method sets the client IAID. 428 * 429 * @param[in] aIaId The client IAID. 430 * 431 */ SetIaid(uint32_t aIaid)432 void SetIaid(uint32_t aIaid) { mIaid = HostSwap32(aIaid); } 433 434 /** 435 * This method returns T1. 436 * 437 * @returns The value of T1. 438 * 439 */ GetT1(void) const440 uint32_t GetT1(void) const { return HostSwap32(mT1); } 441 442 /** 443 * This method sets the value of T1. 444 * 445 * @param[in] aT1 The value of T1. 446 * 447 */ SetT1(uint32_t aT1)448 void SetT1(uint32_t aT1) { mT1 = HostSwap32(aT1); } 449 450 /** 451 * This method returns T2. 452 * 453 * @returns The value of T2. 454 * 455 */ GetT2(void) const456 uint32_t GetT2(void) const { return HostSwap32(mT2); } 457 458 /** 459 * This method sets the value of T2. 460 * 461 * @param[in] aT2 The value of T2. 462 * 463 */ SetT2(uint32_t aT2)464 void SetT2(uint32_t aT2) { mT2 = HostSwap32(aT2); } 465 466 private: 467 uint32_t mIaid; 468 uint32_t mT1; 469 uint32_t mT2; 470 } OT_TOOL_PACKED_END; 471 472 /** 473 * This type represents an Identity Association Address DHCPv6 option. 474 * 475 */ 476 OT_TOOL_PACKED_BEGIN 477 class IaAddress : public Option 478 { 479 public: 480 static constexpr uint32_t kDefaultPreferredLifetime = 0xffffffffU; ///< Default preferred lifetime. 481 static constexpr uint32_t kDefaultValidLiftetime = 0xffffffffU; ///< Default valid lifetime. 482 483 /** 484 * This method initializes the DHCPv6 Option. 485 * 486 */ Init(void)487 void Init(void) 488 { 489 SetCode(kOptionIaAddress); 490 SetLength(sizeof(*this) - sizeof(Option)); 491 } 492 493 /** 494 * This method returns a reference to the IPv6 address. 495 * 496 * @returns A reference to the IPv6 address. 497 * 498 */ GetAddress(void)499 Ip6::Address &GetAddress(void) { return mAddress; } 500 501 /** 502 * This method returns a reference to the IPv6 address. 503 * 504 * @returns A reference to the IPv6 address. 505 * 506 */ GetAddress(void) const507 const Ip6::Address &GetAddress(void) const { return mAddress; } 508 509 /** 510 * This method sets the IPv6 address. 511 * 512 * @param[in] aAddress The reference to the IPv6 address to set. 513 * 514 */ SetAddress(const Ip6::Address & aAddress)515 void SetAddress(const Ip6::Address &aAddress) { mAddress = aAddress; } 516 517 /** 518 * This method returns the preferred lifetime of the IPv6 address. 519 * 520 * @returns The preferred lifetime of the IPv6 address. 521 * 522 */ GetPreferredLifetime(void) const523 uint32_t GetPreferredLifetime(void) const { return HostSwap32(mPreferredLifetime); } 524 525 /** 526 * This method sets the preferred lifetime of the IPv6 address. 527 * 528 * @param[in] aPreferredLifetime The preferred lifetime of the IPv6 address. 529 * 530 */ SetPreferredLifetime(uint32_t aPreferredLifetime)531 void SetPreferredLifetime(uint32_t aPreferredLifetime) { mPreferredLifetime = HostSwap32(aPreferredLifetime); } 532 533 /** 534 * This method returns the valid lifetime of the IPv6 address. 535 * 536 * @returns The valid lifetime of the IPv6 address. 537 * 538 */ GetValidLifetime(void) const539 uint32_t GetValidLifetime(void) const { return HostSwap32(mValidLifetime); } 540 541 /** 542 * This method sets the valid lifetime of the IPv6 address. 543 * 544 * @param[in] aValidLifetime The valid lifetime of the IPv6 address. 545 * 546 */ SetValidLifetime(uint32_t aValidLifetime)547 void SetValidLifetime(uint32_t aValidLifetime) { mValidLifetime = HostSwap32(aValidLifetime); } 548 549 private: 550 Ip6::Address mAddress; 551 uint32_t mPreferredLifetime; 552 uint32_t mValidLifetime; 553 } OT_TOOL_PACKED_END; 554 555 /** 556 * This type represents an Elapsed Time DHCPv6 option. 557 * 558 */ 559 OT_TOOL_PACKED_BEGIN 560 class ElapsedTime : public Option 561 { 562 public: 563 /** 564 * This method initializes the DHCPv6 Option. 565 * 566 */ Init(void)567 void Init(void) 568 { 569 SetCode(kOptionElapsedTime); 570 SetLength(sizeof(*this) - sizeof(Option)); 571 } 572 573 /** 574 * This method returns the elapsed time since solicit starts. 575 * 576 * @returns The elapsed time since solicit starts. 577 * 578 */ GetElapsedTime(void) const579 uint16_t GetElapsedTime(void) const { return HostSwap16(mElapsedTime); } 580 581 /** 582 * This method sets the elapsed time since solicit starts. 583 * 584 * @param[in] aElapsedTime The elapsed time since solicit starts. 585 * 586 */ SetElapsedTime(uint16_t aElapsedTime)587 void SetElapsedTime(uint16_t aElapsedTime) { mElapsedTime = HostSwap16(aElapsedTime); } 588 589 private: 590 uint16_t mElapsedTime; 591 } OT_TOOL_PACKED_END; 592 593 /** 594 * Status Code. 595 * 596 */ 597 enum Status : uint16_t 598 { 599 kStatusSuccess = 0, 600 kStatusUnspecFail = 1, 601 kStatusNoAddrsAvail = 2, 602 kStatusNoBinding = 3, 603 kStatusNotOnLink = 4, 604 kStatusUseMulticast = 5, 605 kUnknownQueryType = 7, 606 kMalformedQuery = 8, 607 kNotConfigured = 9, 608 kNotAllowed = 10, 609 }; 610 611 /** 612 * This type represents an Status Code DHCPv6 option. 613 * 614 */ 615 OT_TOOL_PACKED_BEGIN 616 class StatusCode : public Option 617 { 618 public: 619 /** 620 * This method initializes the DHCPv6 Option. 621 * 622 */ Init(void)623 void Init(void) 624 { 625 SetCode(kOptionStatusCode); 626 SetLength(sizeof(*this) - sizeof(Option)); 627 } 628 629 /** 630 * This method returns the status code. 631 * 632 * @returns The status code. 633 * 634 */ GetStatusCode(void) const635 Status GetStatusCode(void) const { return static_cast<Status>(HostSwap16(mStatus)); } 636 637 /** 638 * This method sets the status code. 639 * 640 * @param[in] aStatus The status code. 641 * 642 */ SetStatusCode(Status aStatus)643 void SetStatusCode(Status aStatus) { mStatus = HostSwap16(static_cast<uint16_t>(aStatus)); } 644 645 private: 646 uint16_t mStatus; 647 } OT_TOOL_PACKED_END; 648 649 /** 650 * This type represents an Rapid Commit DHCPv6 option. 651 * 652 */ 653 OT_TOOL_PACKED_BEGIN 654 class RapidCommit : public Option 655 { 656 public: 657 /** 658 * This method initializes the DHCPv6 Option. 659 * 660 */ Init(void)661 void Init(void) 662 { 663 SetCode(kOptionRapidCommit); 664 SetLength(sizeof(*this) - sizeof(Option)); 665 } 666 } OT_TOOL_PACKED_END; 667 668 } // namespace Dhcp6 669 } // namespace ot 670 671 #endif // DHCP6_HPP_ 672