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