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 * 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 * 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) 111 { 112 OT_UNUSED_VARIABLE(m8); 113 114 return Random::Crypto::Fill(*this); 115 } 116 117 private: 118 uint8_t m8[kSize]; 119 } OT_TOOL_PACKED_END; 120 121 /** 122 * Implements DHCPv6 header. 123 * 124 */ 125 OT_TOOL_PACKED_BEGIN 126 class Header : public Clearable<Header> 127 { 128 public: 129 /** 130 * Returns the DHCPv6 message type. 131 * 132 * @returns The DHCPv6 message type. 133 * 134 */ GetType(void) const135 Type GetType(void) const { return mType; } 136 137 /** 138 * Sets the DHCPv6 message type. 139 * 140 * @param[in] aType The DHCPv6 message type. 141 * 142 */ SetType(Type aType)143 void SetType(Type aType) { mType = aType; } 144 145 /** 146 * Returns the DHCPv6 message transaction identifier. 147 * 148 * @returns The DHCPv6 message transaction identifier. 149 * 150 */ GetTransactionId(void) const151 const TransactionId &GetTransactionId(void) const { return mTransactionId; } 152 153 /** 154 * Sets the DHCPv6 message transaction identifier. 155 * 156 * @param[in] aTransactionId The DHCPv6 message transaction identifier. 157 * 158 */ SetTransactionId(const TransactionId & aTransactionId)159 void SetTransactionId(const TransactionId &aTransactionId) { mTransactionId = aTransactionId; } 160 161 private: 162 Type mType; 163 TransactionId mTransactionId; 164 } OT_TOOL_PACKED_END; 165 166 /** 167 * DHCPv6 Option Codes. 168 * 169 */ 170 enum Code : uint16_t 171 { 172 kOptionClientIdentifier = 1, 173 kOptionServerIdentifier = 2, 174 kOptionIaNa = 3, 175 kOptionIaTa = 4, 176 kOptionIaAddress = 5, 177 kOptionRequestOption = 6, 178 kOptionPreference = 7, 179 kOptionElapsedTime = 8, 180 kOptionRelayMessage = 9, 181 kOptionAuthentication = 11, 182 kOptionServerUnicast = 12, 183 kOptionStatusCode = 13, 184 kOptionRapidCommit = 14, 185 kOptionUserClass = 15, 186 kOptionVendorClass = 16, 187 kOptionVendorSpecificInformation = 17, 188 kOptionInterfaceId = 18, 189 kOptionReconfigureMessage = 19, 190 kOptionReconfigureAccept = 20, 191 kOptionLeaseQuery = 44, 192 kOptionClientData = 45, 193 kOptionClientLastTransactionTime = 46, 194 }; 195 196 /** 197 * Implements DHCPv6 option. 198 * 199 */ 200 OT_TOOL_PACKED_BEGIN 201 class Option 202 { 203 public: 204 /** 205 * Initializes the DHCPv6 option to all zeros. 206 * 207 */ Init(void)208 void Init(void) 209 { 210 mCode = 0; 211 mLength = 0; 212 } 213 214 /** 215 * Returns the DHCPv6 option code. 216 * 217 * @returns The DHCPv6 option code. 218 * 219 */ GetCode(void) const220 Code GetCode(void) const { return static_cast<Code>(HostSwap16(mCode)); } 221 222 /** 223 * Sets the DHCPv6 option code. 224 * 225 * @param[in] aCode The DHCPv6 option code. 226 * 227 */ SetCode(Code aCode)228 void SetCode(Code aCode) { mCode = HostSwap16(static_cast<uint16_t>(aCode)); } 229 230 /** 231 * Returns the length of DHCPv6 option. 232 * 233 * @returns The length of DHCPv6 option. 234 * 235 */ GetLength(void) const236 uint16_t GetLength(void) const { return HostSwap16(mLength); } 237 238 /** 239 * Sets the length of DHCPv6 option. 240 * 241 * @param[in] aLength The length of DHCPv6 option. 242 * 243 */ SetLength(uint16_t aLength)244 void SetLength(uint16_t aLength) { mLength = HostSwap16(aLength); } 245 246 private: 247 uint16_t mCode; 248 uint16_t mLength; 249 } OT_TOOL_PACKED_END; 250 251 /** 252 * DHCP6 Unique Identifier (DUID) Type. 253 * 254 */ 255 enum DuidType : uint16_t 256 { 257 kDuidLinkLayerAddressPlusTime = 1, ///< Link-layer address plus time (DUID-LLT). 258 kDuidEnterpriseNumber = 2, ///< Vendor-assigned unique ID based on Enterprise Number (DUID-EN). 259 kDuidLinkLayerAddress = 3, ///< Link-layer address (DUID-LL). 260 }; 261 262 OT_TOOL_PACKED_BEGIN 263 class ClientIdentifier : public Option 264 { 265 public: 266 /** 267 * Initializes the DHCPv6 Option. 268 * 269 */ Init(void)270 void Init(void) 271 { 272 SetCode(kOptionClientIdentifier); 273 SetLength(sizeof(*this) - sizeof(Option)); 274 } 275 276 /** 277 * Returns the client DUID Type. 278 * 279 * @returns The client DUID Type. 280 * 281 */ GetDuidType(void) const282 DuidType GetDuidType(void) const { return static_cast<DuidType>(HostSwap16(mDuidType)); } 283 284 /** 285 * Sets the client DUID Type. 286 * 287 * @param[in] aDuidType The client DUID Type. 288 * 289 */ SetDuidType(DuidType aDuidType)290 void SetDuidType(DuidType aDuidType) { mDuidType = HostSwap16(static_cast<uint16_t>(aDuidType)); } 291 292 /** 293 * Returns the client Duid HardwareType. 294 * 295 * @returns The client Duid HardwareType. 296 * 297 */ GetDuidHardwareType(void) const298 uint16_t GetDuidHardwareType(void) const { return HostSwap16(mDuidHardwareType); } 299 300 /** 301 * Sets the client Duid HardwareType. 302 * 303 * @param[in] aDuidHardwareType The client Duid HardwareType. 304 * 305 */ SetDuidHardwareType(uint16_t aDuidHardwareType)306 void SetDuidHardwareType(uint16_t aDuidHardwareType) { mDuidHardwareType = HostSwap16(aDuidHardwareType); } 307 308 /** 309 * Returns the client LinkLayerAddress. 310 * 311 * @returns The link-layer address. 312 * 313 */ GetDuidLinkLayerAddress(void) const314 const Mac::ExtAddress &GetDuidLinkLayerAddress(void) const { return mDuidLinkLayerAddress; } 315 316 /** 317 * Sets the client LinkLayerAddress. 318 * 319 * @param[in] aDuidLinkLayerAddress The client LinkLayerAddress. 320 * 321 */ SetDuidLinkLayerAddress(const Mac::ExtAddress & aDuidLinkLayerAddress)322 void SetDuidLinkLayerAddress(const Mac::ExtAddress &aDuidLinkLayerAddress) 323 { 324 mDuidLinkLayerAddress = aDuidLinkLayerAddress; 325 } 326 327 private: 328 uint16_t mDuidType; 329 uint16_t mDuidHardwareType; 330 Mac::ExtAddress mDuidLinkLayerAddress; 331 } OT_TOOL_PACKED_END; 332 333 OT_TOOL_PACKED_BEGIN 334 class ServerIdentifier : public Option 335 { 336 public: 337 /** 338 * Initializes the DHCPv6 Option. 339 * 340 */ Init(void)341 void Init(void) 342 { 343 SetCode(kOptionServerIdentifier); 344 SetLength(sizeof(*this) - sizeof(Option)); 345 } 346 347 /** 348 * Returns the server DUID Type. 349 * 350 * @returns The server DUID Type. 351 * 352 */ GetDuidType(void) const353 DuidType GetDuidType(void) const { return static_cast<DuidType>(HostSwap16(mDuidType)); } 354 355 /** 356 * Sets the server DUID Type. 357 * 358 * @param[in] aDuidType The server DUID Type. 359 * 360 */ SetDuidType(DuidType aDuidType)361 void SetDuidType(DuidType aDuidType) { mDuidType = HostSwap16(static_cast<uint16_t>(aDuidType)); } 362 363 /** 364 * Returns the server DUID HardwareType. 365 * 366 * @returns The server DUID HardwareType. 367 * 368 */ GetDuidHardwareType(void) const369 uint16_t GetDuidHardwareType(void) const { return HostSwap16(mDuidHardwareType); } 370 371 /** 372 * Sets the server DUID HardwareType. 373 * 374 * @param[in] aDuidHardwareType The server DUID HardwareType. 375 * 376 */ SetDuidHardwareType(uint16_t aDuidHardwareType)377 void SetDuidHardwareType(uint16_t aDuidHardwareType) { mDuidHardwareType = HostSwap16(aDuidHardwareType); } 378 379 /** 380 * Returns the server LinkLayerAddress. 381 * 382 * @returns The link-layer address. 383 * 384 */ GetDuidLinkLayerAddress(void) const385 const Mac::ExtAddress &GetDuidLinkLayerAddress(void) const { return mDuidLinkLayerAddress; } 386 387 /** 388 * Sets the server LinkLayerAddress. 389 * 390 * @param[in] aDuidLinkLayerAddress The server LinkLayerAddress. 391 * 392 */ SetDuidLinkLayerAddress(const Mac::ExtAddress & aDuidLinkLayerAddress)393 void SetDuidLinkLayerAddress(const Mac::ExtAddress &aDuidLinkLayerAddress) 394 { 395 mDuidLinkLayerAddress = aDuidLinkLayerAddress; 396 } 397 398 private: 399 uint16_t mDuidType; 400 uint16_t mDuidHardwareType; 401 Mac::ExtAddress mDuidLinkLayerAddress; 402 } OT_TOOL_PACKED_END; 403 404 /** 405 * Represents an Identity Association for Non-temporary Address DHCPv6 option. 406 * 407 */ 408 OT_TOOL_PACKED_BEGIN 409 class IaNa : public Option 410 { 411 public: 412 static constexpr uint32_t kDefaultT1 = 0xffffffffU; ///< Default T1 value. 413 static constexpr uint32_t kDefaultT2 = 0xffffffffU; ///< Default T2 value. 414 415 /** 416 * Initializes the DHCPv6 Option. 417 * 418 */ Init(void)419 void Init(void) 420 { 421 SetCode(kOptionIaNa); 422 SetLength(sizeof(*this) - sizeof(Option)); 423 } 424 425 /** 426 * Returns client IAID. 427 * 428 * @returns The client IAID. 429 * 430 */ GetIaid(void) const431 uint32_t GetIaid(void) const { return HostSwap32(mIaid); } 432 433 /** 434 * Sets the client IAID. 435 * 436 * @param[in] aIaid The client IAID. 437 * 438 */ SetIaid(uint32_t aIaid)439 void SetIaid(uint32_t aIaid) { mIaid = HostSwap32(aIaid); } 440 441 /** 442 * Returns T1. 443 * 444 * @returns The value of T1. 445 * 446 */ GetT1(void) const447 uint32_t GetT1(void) const { return HostSwap32(mT1); } 448 449 /** 450 * Sets the value of T1. 451 * 452 * @param[in] aT1 The value of T1. 453 * 454 */ SetT1(uint32_t aT1)455 void SetT1(uint32_t aT1) { mT1 = HostSwap32(aT1); } 456 457 /** 458 * Returns T2. 459 * 460 * @returns The value of T2. 461 * 462 */ GetT2(void) const463 uint32_t GetT2(void) const { return HostSwap32(mT2); } 464 465 /** 466 * Sets the value of T2. 467 * 468 * @param[in] aT2 The value of T2. 469 * 470 */ SetT2(uint32_t aT2)471 void SetT2(uint32_t aT2) { mT2 = HostSwap32(aT2); } 472 473 private: 474 uint32_t mIaid; 475 uint32_t mT1; 476 uint32_t mT2; 477 } OT_TOOL_PACKED_END; 478 479 /** 480 * Represents an Identity Association Address DHCPv6 option. 481 * 482 */ 483 OT_TOOL_PACKED_BEGIN 484 class IaAddress : public Option 485 { 486 public: 487 static constexpr uint32_t kDefaultPreferredLifetime = 0xffffffffU; ///< Default preferred lifetime. 488 static constexpr uint32_t kDefaultValidLifetime = 0xffffffffU; ///< Default valid lifetime. 489 490 /** 491 * Initializes the DHCPv6 Option. 492 * 493 */ Init(void)494 void Init(void) 495 { 496 SetCode(kOptionIaAddress); 497 SetLength(sizeof(*this) - sizeof(Option)); 498 } 499 500 /** 501 * Returns a reference to the IPv6 address. 502 * 503 * @returns A reference to the IPv6 address. 504 * 505 */ GetAddress(void)506 Ip6::Address &GetAddress(void) { return mAddress; } 507 508 /** 509 * Returns a reference to the IPv6 address. 510 * 511 * @returns A reference to the IPv6 address. 512 * 513 */ GetAddress(void) const514 const Ip6::Address &GetAddress(void) const { return mAddress; } 515 516 /** 517 * Sets the IPv6 address. 518 * 519 * @param[in] aAddress The reference to the IPv6 address to set. 520 * 521 */ SetAddress(const Ip6::Address & aAddress)522 void SetAddress(const Ip6::Address &aAddress) { mAddress = aAddress; } 523 524 /** 525 * Returns the preferred lifetime of the IPv6 address. 526 * 527 * @returns The preferred lifetime of the IPv6 address. 528 * 529 */ GetPreferredLifetime(void) const530 uint32_t GetPreferredLifetime(void) const { return HostSwap32(mPreferredLifetime); } 531 532 /** 533 * Sets the preferred lifetime of the IPv6 address. 534 * 535 * @param[in] aPreferredLifetime The preferred lifetime of the IPv6 address. 536 * 537 */ SetPreferredLifetime(uint32_t aPreferredLifetime)538 void SetPreferredLifetime(uint32_t aPreferredLifetime) { mPreferredLifetime = HostSwap32(aPreferredLifetime); } 539 540 /** 541 * Returns the valid lifetime of the IPv6 address. 542 * 543 * @returns The valid lifetime of the IPv6 address. 544 * 545 */ GetValidLifetime(void) const546 uint32_t GetValidLifetime(void) const { return HostSwap32(mValidLifetime); } 547 548 /** 549 * Sets the valid lifetime of the IPv6 address. 550 * 551 * @param[in] aValidLifetime The valid lifetime of the IPv6 address. 552 * 553 */ SetValidLifetime(uint32_t aValidLifetime)554 void SetValidLifetime(uint32_t aValidLifetime) { mValidLifetime = HostSwap32(aValidLifetime); } 555 556 private: 557 Ip6::Address mAddress; 558 uint32_t mPreferredLifetime; 559 uint32_t mValidLifetime; 560 } OT_TOOL_PACKED_END; 561 562 /** 563 * Represents an Elapsed Time DHCPv6 option. 564 * 565 */ 566 OT_TOOL_PACKED_BEGIN 567 class ElapsedTime : public Option 568 { 569 public: 570 /** 571 * Initializes the DHCPv6 Option. 572 * 573 */ Init(void)574 void Init(void) 575 { 576 SetCode(kOptionElapsedTime); 577 SetLength(sizeof(*this) - sizeof(Option)); 578 } 579 580 /** 581 * Returns the elapsed time since solicit starts. 582 * 583 * @returns The elapsed time since solicit starts. 584 * 585 */ GetElapsedTime(void) const586 uint16_t GetElapsedTime(void) const { return HostSwap16(mElapsedTime); } 587 588 /** 589 * Sets the elapsed time since solicit starts. 590 * 591 * @param[in] aElapsedTime The elapsed time since solicit starts. 592 * 593 */ SetElapsedTime(uint16_t aElapsedTime)594 void SetElapsedTime(uint16_t aElapsedTime) { mElapsedTime = HostSwap16(aElapsedTime); } 595 596 private: 597 uint16_t mElapsedTime; 598 } OT_TOOL_PACKED_END; 599 600 /** 601 * Status Code. 602 * 603 */ 604 enum Status : uint16_t 605 { 606 kStatusSuccess = 0, 607 kStatusUnspecFail = 1, 608 kStatusNoAddrsAvail = 2, 609 kStatusNoBinding = 3, 610 kStatusNotOnLink = 4, 611 kStatusUseMulticast = 5, 612 kUnknownQueryType = 7, 613 kMalformedQuery = 8, 614 kNotConfigured = 9, 615 kNotAllowed = 10, 616 }; 617 618 /** 619 * Represents an Status Code DHCPv6 option. 620 * 621 */ 622 OT_TOOL_PACKED_BEGIN 623 class StatusCode : public Option 624 { 625 public: 626 /** 627 * Initializes the DHCPv6 Option. 628 * 629 */ Init(void)630 void Init(void) 631 { 632 SetCode(kOptionStatusCode); 633 SetLength(sizeof(*this) - sizeof(Option)); 634 } 635 636 /** 637 * Returns the status code. 638 * 639 * @returns The status code. 640 * 641 */ GetStatusCode(void) const642 Status GetStatusCode(void) const { return static_cast<Status>(HostSwap16(mStatus)); } 643 644 /** 645 * Sets the status code. 646 * 647 * @param[in] aStatus The status code. 648 * 649 */ SetStatusCode(Status aStatus)650 void SetStatusCode(Status aStatus) { mStatus = HostSwap16(static_cast<uint16_t>(aStatus)); } 651 652 private: 653 uint16_t mStatus; 654 } OT_TOOL_PACKED_END; 655 656 /** 657 * Represents an Rapid Commit DHCPv6 option. 658 * 659 */ 660 OT_TOOL_PACKED_BEGIN 661 class RapidCommit : public Option 662 { 663 public: 664 /** 665 * Initializes the DHCPv6 Option. 666 * 667 */ Init(void)668 void Init(void) 669 { 670 SetCode(kOptionRapidCommit); 671 SetLength(sizeof(*this) - sizeof(Option)); 672 } 673 } OT_TOOL_PACKED_END; 674 675 } // namespace Dhcp6 676 } // namespace ot 677 678 #endif // #if OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE || OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE 679 680 #endif // DHCP6_HPP_ 681