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 /** 84 * Applies the Mesh Local Prefix. 85 * 86 */ 87 void ApplyMeshLocalPrefix(void); 88 89 private: 90 class PrefixAgent 91 { 92 public: 93 /** 94 * Indicates whether or not @p aAddress has a matching prefix. 95 * 96 * @param[in] aAddress The IPv6 address to compare. 97 * 98 * @retval TRUE if the address has a matching prefix. 99 * @retval FALSE if the address does not have a matching prefix. 100 * 101 */ IsPrefixMatch(const Ip6::Address & aAddress) const102 bool IsPrefixMatch(const Ip6::Address &aAddress) const { return aAddress.MatchesPrefix(GetPrefix()); } 103 104 /** 105 * Indicates whether or not this entry is valid. 106 * 107 * @retval TRUE if this entry is valid. 108 * @retval FALSE if this entry is not valid. 109 * 110 */ IsValid(void) const111 bool IsValid(void) const { return mAloc.mValid; } 112 113 /** 114 * Sets the entry to invalid. 115 * 116 */ Clear(void)117 void Clear(void) { mAloc.mValid = false; } 118 119 /** 120 * Returns the 6LoWPAN context ID. 121 * 122 * @returns The 6LoWPAN context ID. 123 * 124 */ GetContextId(void) const125 uint8_t GetContextId(void) const { return mAloc.mAddress.mFields.m8[15]; } 126 127 /** 128 * Returns the ALOC. 129 * 130 * @returns the ALOC. 131 * 132 */ GetAloc(void)133 Ip6::Netif::UnicastAddress &GetAloc(void) { return mAloc; } 134 135 /** 136 * Returns the IPv6 prefix. 137 * 138 * @returns The IPv6 prefix. 139 * 140 */ GetPrefix(void) const141 const Ip6::Prefix &GetPrefix(void) const { return mPrefix; } 142 143 /** 144 * Returns the IPv6 prefix. 145 * 146 * @returns The IPv6 prefix. 147 * 148 */ GetPrefix(void)149 Ip6::Prefix &GetPrefix(void) { return mPrefix; } 150 151 /** 152 * Returns the IPv6 prefix as an IPv6 address. 153 * 154 * @returns The IPv6 prefix as an IPv6 address. 155 * 156 */ GetPrefixAsAddress(void) const157 const Ip6::Address &GetPrefixAsAddress(void) const 158 { 159 return static_cast<const Ip6::Address &>(mPrefix.mPrefix); 160 } 161 162 /** 163 * Sets the ALOC. 164 * 165 * @param[in] aPrefix The IPv6 prefix. 166 * @param[in] aMeshLocalPrefix The Mesh Local Prefix. 167 * @param[in] aContextId The 6LoWPAN Context ID. 168 * 169 */ Set(const Ip6::Prefix & aPrefix,const Ip6::NetworkPrefix & aMeshLocalPrefix,uint8_t aContextId)170 void Set(const Ip6::Prefix &aPrefix, const Ip6::NetworkPrefix &aMeshLocalPrefix, uint8_t aContextId) 171 { 172 mPrefix = aPrefix; 173 174 mAloc.InitAsThreadOrigin(); 175 mAloc.GetAddress().SetToAnycastLocator(aMeshLocalPrefix, (Ip6::Address::kAloc16Mask << 8) + aContextId); 176 } 177 178 private: 179 Ip6::Netif::UnicastAddress mAloc; 180 Ip6::Prefix mPrefix; 181 }; 182 183 static constexpr uint16_t kNumPrefixes = OPENTHREAD_CONFIG_DHCP6_SERVER_NUM_PREFIXES; 184 185 void Start(void); 186 void Stop(void); 187 188 void AddPrefixAgent(const Ip6::Prefix &aIp6Prefix, const Lowpan::Context &aContext); 189 190 Error AppendHeader(Message &aMessage, const TransactionId &aTransactionId); 191 Error AppendClientIdentifier(Message &aMessage, ClientIdentifier &aClientId); 192 Error AppendServerIdentifier(Message &aMessage); 193 Error AppendIaNa(Message &aMessage, IaNa &aIaNa); 194 Error AppendStatusCode(Message &aMessage, Status aStatusCode); 195 Error AppendIaAddress(Message &aMessage, ClientIdentifier &aClientId); 196 Error AppendRapidCommit(Message &aMessage); 197 Error AppendVendorSpecificInformation(Message &aMessage); 198 199 Error AddIaAddress(Message &aMessage, const Ip6::Address &aPrefix, ClientIdentifier &aClientId); 200 201 static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo); 202 void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 203 204 void ProcessSolicit(Message &aMessage, const Ip6::Address &aDst, const TransactionId &aTransactionId); 205 206 uint16_t FindOption(Message &aMessage, uint16_t aOffset, uint16_t aLength, Code aCode); 207 Error ProcessClientIdentifier(Message &aMessage, uint16_t aOffset, ClientIdentifier &aClientId); 208 Error ProcessIaNa(Message &aMessage, uint16_t aOffset, IaNa &aIaNa); 209 Error ProcessIaAddress(Message &aMessage, uint16_t aOffset); 210 Error ProcessElapsedTime(Message &aMessage, uint16_t aOffset); 211 212 Error SendReply(const Ip6::Address &aDst, 213 const TransactionId &aTransactionId, 214 ClientIdentifier &aClientId, 215 IaNa &aIaNa); 216 217 Ip6::Udp::Socket mSocket; 218 219 PrefixAgent mPrefixAgents[kNumPrefixes]; 220 uint8_t mPrefixAgentsCount; 221 uint8_t mPrefixAgentsMask; 222 }; 223 224 /** 225 * @} 226 * 227 */ 228 229 } // namespace Dhcp6 230 } // namespace ot 231 232 #endif // OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE 233 234 #endif // DHCP6_SERVER_HPP_ 235