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