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 Client.
32  */
33 
34 #ifndef DHCP6_CLIENT_HPP_
35 #define DHCP6_CLIENT_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #if OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE
40 
41 #include "common/locator.hpp"
42 #include "common/message.hpp"
43 #include "common/non_copyable.hpp"
44 #include "common/timer.hpp"
45 #include "common/trickle_timer.hpp"
46 #include "mac/mac.hpp"
47 #include "mac/mac_types.hpp"
48 #include "net/dhcp6.hpp"
49 #include "net/netif.hpp"
50 #include "net/udp6.hpp"
51 
52 namespace ot {
53 
54 namespace Dhcp6 {
55 
56 /**
57  * @addtogroup core-dhcp6
58  *
59  * @brief
60  *   This module includes definitions for DHCPv6 Client.
61  *
62  * @{
63  *
64  */
65 
66 /**
67  * This class implements DHCPv6 Client.
68  *
69  */
70 class Client : public InstanceLocator, private NonCopyable
71 {
72 public:
73     /**
74      * This constructor initializes the object.
75      *
76      * @param[in]  aInstance     A reference to the OpenThread instance.
77      *
78      */
79     explicit Client(Instance &aInstance);
80 
81     /**
82      * This method update addresses that shall be automatically created using DHCP.
83      *
84      *
85      */
86     void UpdateAddresses(void);
87 
88 private:
89     static constexpr uint32_t kTrickleTimerImin = 1;
90     static constexpr uint32_t kTrickleTimerImax = 120;
91 
92     enum IaStatus : uint8_t
93     {
94         kIaStatusInvalid,
95         kIaStatusSolicit,
96         kIaStatusSoliciting,
97         kIaStatusSolicitReplied,
98     };
99 
100     struct IdentityAssociation
101     {
102         Ip6::Netif::UnicastAddress mNetifAddress;
103         uint32_t                   mPreferredLifetime;
104         uint32_t                   mValidLifetime;
105         uint16_t                   mPrefixAgentRloc;
106         IaStatus                   mStatus;
107     };
108 
109     void Start(void);
110     void Stop(void);
111 
112     static bool MatchNetifAddressWithPrefix(const Ip6::Netif::UnicastAddress &aNetifAddress,
113                                             const Ip6::Prefix &               aIp6Prefix);
114 
115     void Solicit(uint16_t aRloc16);
116 
117     void AddIdentityAssociation(uint16_t aRloc16, otIp6Prefix &aIp6Prefix);
118     void RemoveIdentityAssociation(uint16_t aRloc16, otIp6Prefix &aIp6Prefix);
119 
120     bool ProcessNextIdentityAssociation(void);
121 
122     Error AppendHeader(Message &aMessage);
123     Error AppendClientIdentifier(Message &aMessage);
124     Error AppendIaNa(Message &aMessage, uint16_t aRloc16);
125     Error AppendIaAddress(Message &aMessage, uint16_t aRloc16);
126     Error AppendElapsedTime(Message &aMessage);
127     Error AppendRapidCommit(Message &aMessage);
128 
129     static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
130     void        HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
131 
132     void     ProcessReply(Message &aMessage);
133     uint16_t FindOption(Message &aMessage, uint16_t aOffset, uint16_t aLength, Code aCode);
134     Error    ProcessServerIdentifier(Message &aMessage, uint16_t aOffset);
135     Error    ProcessClientIdentifier(Message &aMessage, uint16_t aOffset);
136     Error    ProcessIaNa(Message &aMessage, uint16_t aOffset);
137     Error    ProcessStatusCode(Message &aMessage, uint16_t aOffset);
138     Error    ProcessIaAddress(Message &aMessage, uint16_t aOffset);
139 
140     static void HandleTrickleTimer(TrickleTimer &aTrickleTimer);
141     void        HandleTrickleTimer(void);
142 
143     Ip6::Udp::Socket mSocket;
144 
145     TrickleTimer mTrickleTimer;
146 
147     TransactionId mTransactionId;
148     TimeMilli     mStartTime;
149 
150     IdentityAssociation  mIdentityAssociations[OPENTHREAD_CONFIG_DHCP6_CLIENT_NUM_PREFIXES];
151     IdentityAssociation *mIdentityAssociationCurrent;
152 };
153 
154 /**
155  * @}
156  *
157  */
158 
159 } // namespace Dhcp6
160 } // namespace ot
161 
162 #else // OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE
163 
164 #if OPENTHREAD_ENABLE_DHCP6_MULTICAST_SOLICIT
165 #error "OPENTHREAD_ENABLE_DHCP6_MULTICAST_SOLICIT requires OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE to be also set."
166 #endif
167 
168 #endif // OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE
169 
170 #endif // DHCP6_CLIENT_HPP_
171