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 Server. 32 */ 33 34 #ifndef DHCP6_SERVER_HPP_ 35 #define DHCP6_SERVER_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #if OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE 40 41 #include "common/locator.hpp" 42 #include "common/non_copyable.hpp" 43 #include "mac/mac.hpp" 44 #include "mac/mac_types.hpp" 45 #include "net/dhcp6.hpp" 46 #include "net/udp6.hpp" 47 #include "thread/network_data_leader.hpp" 48 49 namespace ot { 50 namespace Dhcp6 { 51 52 #if OPENTHREAD_ENABLE_DHCP6_MULTICAST_SOLICIT 53 #error "OPENTHREAD_ENABLE_DHCP6_MULTICAST_SOLICIT requires DHCPv6 server on Border Router side to be enabled." 54 #endif 55 56 /** 57 * @addtogroup core-dhcp6 58 * 59 * @brief 60 * This module includes definitions for DHCPv6 Server. 61 * 62 * @{ 63 * 64 */ 65 66 class Server : public InstanceLocator, private NonCopyable 67 { 68 public: 69 /** 70 * Initializes the object. 71 * 72 * @param[in] aInstance A reference to the OpenThread instance. 73 * 74 */ 75 explicit Server(Instance &aInstance); 76 77 /** 78 * Updates DHCP Agents and DHCP ALOCs. 79 * 80 */ 81 Error UpdateService(void); 82 83 private: 84 class PrefixAgent 85 { 86 public: 87 /** 88 * Indicates whether or not @p aAddress has a matching prefix. 89 * 90 * @param[in] aAddress The IPv6 address to compare. 91 * 92 * @retval TRUE if the address has a matching prefix. 93 * @retval FALSE if the address does not have a matching prefix. 94 * 95 */ IsPrefixMatch(const Ip6::Address & aAddress) const96 bool IsPrefixMatch(const Ip6::Address &aAddress) const { return aAddress.MatchesPrefix(GetPrefix()); } 97 98 /** 99 * Indicates whether or not this entry is valid. 100 * 101 * @retval TRUE if this entry is valid. 102 * @retval FALSE if this entry is not valid. 103 * 104 */ IsValid(void) const105 bool IsValid(void) const { return mAloc.mValid; } 106 107 /** 108 * Sets the entry to invalid. 109 * 110 */ Clear(void)111 void Clear(void) { mAloc.mValid = false; } 112 113 /** 114 * Returns the 6LoWPAN context ID. 115 * 116 * @returns The 6LoWPAN context ID. 117 * 118 */ GetContextId(void) const119 uint8_t GetContextId(void) const { return mAloc.mAddress.mFields.m8[15]; } 120 121 /** 122 * Returns the ALOC. 123 * 124 * @returns the ALOC. 125 * 126 */ GetAloc(void)127 Ip6::Netif::UnicastAddress &GetAloc(void) { return mAloc; } 128 129 /** 130 * Returns the IPv6 prefix. 131 * 132 * @returns The IPv6 prefix. 133 * 134 */ GetPrefix(void) const135 const Ip6::Prefix &GetPrefix(void) const { return mPrefix; } 136 137 /** 138 * Returns the IPv6 prefix. 139 * 140 * @returns The IPv6 prefix. 141 * 142 */ GetPrefix(void)143 Ip6::Prefix &GetPrefix(void) { return mPrefix; } 144 145 /** 146 * Returns the IPv6 prefix as an IPv6 address. 147 * 148 * @returns The IPv6 prefix as an IPv6 address. 149 * 150 */ GetPrefixAsAddress(void) const151 const Ip6::Address &GetPrefixAsAddress(void) const 152 { 153 return static_cast<const Ip6::Address &>(mPrefix.mPrefix); 154 } 155 156 /** 157 * Sets the ALOC. 158 * 159 * @param[in] aPrefix The IPv6 prefix. 160 * @param[in] aMeshLocalPrefix The Mesh Local Prefix. 161 * @param[in] aContextId The 6LoWPAN Context ID. 162 * 163 */ Set(const Ip6::Prefix & aPrefix,const Ip6::NetworkPrefix & aMeshLocalPrefix,uint8_t aContextId)164 void Set(const Ip6::Prefix &aPrefix, const Ip6::NetworkPrefix &aMeshLocalPrefix, uint8_t aContextId) 165 { 166 mPrefix = aPrefix; 167 168 mAloc.InitAsThreadOrigin(); 169 mAloc.GetAddress().SetToAnycastLocator(aMeshLocalPrefix, (Ip6::Address::kAloc16Mask << 8) + aContextId); 170 mAloc.mMeshLocal = true; 171 } 172 173 private: 174 Ip6::Netif::UnicastAddress mAloc; 175 Ip6::Prefix mPrefix; 176 }; 177 178 static constexpr uint16_t kNumPrefixes = OPENTHREAD_CONFIG_DHCP6_SERVER_NUM_PREFIXES; 179 180 void Start(void); 181 void Stop(void); 182 183 void AddPrefixAgent(const Ip6::Prefix &aIp6Prefix, const Lowpan::Context &aContext); 184 185 Error AppendHeader(Message &aMessage, const TransactionId &aTransactionId); 186 Error AppendClientIdentifier(Message &aMessage, ClientIdentifier &aClientId); 187 Error AppendServerIdentifier(Message &aMessage); 188 Error AppendIaNa(Message &aMessage, IaNa &aIaNa); 189 Error AppendStatusCode(Message &aMessage, Status aStatusCode); 190 Error AppendIaAddress(Message &aMessage, ClientIdentifier &aClientId); 191 Error AppendRapidCommit(Message &aMessage); 192 Error AppendVendorSpecificInformation(Message &aMessage); 193 194 Error AddIaAddress(Message &aMessage, const Ip6::Address &aPrefix, ClientIdentifier &aClientId); 195 void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 196 void ProcessSolicit(Message &aMessage, const Ip6::Address &aDst, const TransactionId &aTransactionId); 197 198 uint16_t FindOption(Message &aMessage, uint16_t aOffset, uint16_t aLength, Code aCode); 199 Error ProcessClientIdentifier(Message &aMessage, uint16_t aOffset, ClientIdentifier &aClientId); 200 Error ProcessIaNa(Message &aMessage, uint16_t aOffset, IaNa &aIaNa); 201 Error ProcessIaAddress(Message &aMessage, uint16_t aOffset); 202 Error ProcessElapsedTime(Message &aMessage, uint16_t aOffset); 203 204 Error SendReply(const Ip6::Address &aDst, 205 const TransactionId &aTransactionId, 206 ClientIdentifier &aClientId, 207 IaNa &aIaNa); 208 209 using ServerSocket = Ip6::Udp::SocketIn<Server, &Server::HandleUdpReceive>; 210 211 ServerSocket mSocket; 212 213 PrefixAgent mPrefixAgents[kNumPrefixes]; 214 uint8_t mPrefixAgentsCount; 215 uint8_t mPrefixAgentsMask; 216 }; 217 218 /** 219 * @} 220 * 221 */ 222 223 } // namespace Dhcp6 224 } // namespace ot 225 226 #endif // OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE 227 228 #endif // DHCP6_SERVER_HPP_ 229