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 class Server : public InstanceLocator, private NonCopyable 66 { 67 public: 68 /** 69 * Initializes the object. 70 * 71 * @param[in] aInstance A reference to the OpenThread instance. 72 */ 73 explicit Server(Instance &aInstance); 74 75 /** 76 * Updates DHCP Agents and DHCP ALOCs. 77 */ 78 Error UpdateService(void); 79 80 private: 81 class PrefixAgent 82 { 83 public: 84 /** 85 * Indicates whether or not @p aAddress has a matching prefix. 86 * 87 * @param[in] aAddress The IPv6 address to compare. 88 * 89 * @retval TRUE if the address has a matching prefix. 90 * @retval FALSE if the address does not have a matching prefix. 91 */ IsPrefixMatch(const Ip6::Address & aAddress) const92 bool IsPrefixMatch(const Ip6::Address &aAddress) const { return aAddress.MatchesPrefix(GetPrefix()); } 93 94 /** 95 * Indicates whether or not this entry is valid. 96 * 97 * @retval TRUE if this entry is valid. 98 * @retval FALSE if this entry is not valid. 99 */ IsValid(void) const100 bool IsValid(void) const { return mAloc.mValid; } 101 102 /** 103 * Sets the entry to invalid. 104 */ Clear(void)105 void Clear(void) { mAloc.mValid = false; } 106 107 /** 108 * Returns the 6LoWPAN context ID. 109 * 110 * @returns The 6LoWPAN context ID. 111 */ GetContextId(void) const112 uint8_t GetContextId(void) const { return mAloc.mAddress.mFields.m8[15]; } 113 114 /** 115 * Returns the ALOC. 116 * 117 * @returns the ALOC. 118 */ GetAloc(void)119 Ip6::Netif::UnicastAddress &GetAloc(void) { return mAloc; } 120 121 /** 122 * Returns the IPv6 prefix. 123 * 124 * @returns The IPv6 prefix. 125 */ GetPrefix(void) const126 const Ip6::Prefix &GetPrefix(void) const { return mPrefix; } 127 128 /** 129 * Returns the IPv6 prefix. 130 * 131 * @returns The IPv6 prefix. 132 */ GetPrefix(void)133 Ip6::Prefix &GetPrefix(void) { return mPrefix; } 134 135 /** 136 * Returns the IPv6 prefix as an IPv6 address. 137 * 138 * @returns The IPv6 prefix as an IPv6 address. 139 */ GetPrefixAsAddress(void) const140 const Ip6::Address &GetPrefixAsAddress(void) const 141 { 142 return static_cast<const Ip6::Address &>(mPrefix.mPrefix); 143 } 144 145 /** 146 * Sets the ALOC. 147 * 148 * @param[in] aPrefix The IPv6 prefix. 149 * @param[in] aMeshLocalPrefix The Mesh Local Prefix. 150 * @param[in] aContextId The 6LoWPAN Context ID. 151 */ Set(const Ip6::Prefix & aPrefix,const Ip6::NetworkPrefix & aMeshLocalPrefix,uint8_t aContextId)152 void Set(const Ip6::Prefix &aPrefix, const Ip6::NetworkPrefix &aMeshLocalPrefix, uint8_t aContextId) 153 { 154 mPrefix = aPrefix; 155 156 mAloc.InitAsThreadOrigin(); 157 mAloc.GetAddress().SetToAnycastLocator(aMeshLocalPrefix, (Ip6::Address::kAloc16Mask << 8) + aContextId); 158 mAloc.mMeshLocal = true; 159 } 160 161 private: 162 Ip6::Netif::UnicastAddress mAloc; 163 Ip6::Prefix mPrefix; 164 }; 165 166 static constexpr uint16_t kNumPrefixes = OPENTHREAD_CONFIG_DHCP6_SERVER_NUM_PREFIXES; 167 168 void Start(void); 169 void Stop(void); 170 171 void AddPrefixAgent(const Ip6::Prefix &aIp6Prefix, const Lowpan::Context &aContext); 172 173 Error AppendHeader(Message &aMessage, const TransactionId &aTransactionId); 174 Error AppendClientIdentifier(Message &aMessage, ClientIdentifier &aClientId); 175 Error AppendServerIdentifier(Message &aMessage); 176 Error AppendIaNa(Message &aMessage, IaNa &aIaNa); 177 Error AppendStatusCode(Message &aMessage, Status aStatusCode); 178 Error AppendIaAddress(Message &aMessage, ClientIdentifier &aClientId); 179 Error AppendRapidCommit(Message &aMessage); 180 Error AppendVendorSpecificInformation(Message &aMessage); 181 182 Error AddIaAddress(Message &aMessage, const Ip6::Address &aPrefix, ClientIdentifier &aClientId); 183 void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 184 void ProcessSolicit(Message &aMessage, const Ip6::Address &aDst, const TransactionId &aTransactionId); 185 186 uint16_t FindOption(Message &aMessage, uint16_t aOffset, uint16_t aLength, Code aCode); 187 Error ProcessClientIdentifier(Message &aMessage, uint16_t aOffset, ClientIdentifier &aClientId); 188 Error ProcessIaNa(Message &aMessage, uint16_t aOffset, IaNa &aIaNa); 189 Error ProcessIaAddress(Message &aMessage, uint16_t aOffset); 190 Error ProcessElapsedTime(Message &aMessage, uint16_t aOffset); 191 192 Error SendReply(const Ip6::Address &aDst, 193 const TransactionId &aTransactionId, 194 ClientIdentifier &aClientId, 195 IaNa &aIaNa); 196 197 using ServerSocket = Ip6::Udp::SocketIn<Server, &Server::HandleUdpReceive>; 198 199 ServerSocket mSocket; 200 201 PrefixAgent mPrefixAgents[kNumPrefixes]; 202 uint8_t mPrefixAgentsCount; 203 uint8_t mPrefixAgentsMask; 204 }; 205 206 /** 207 * @} 208 */ 209 210 } // namespace Dhcp6 211 } // namespace ot 212 213 #endif // OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE 214 215 #endif // DHCP6_SERVER_HPP_ 216