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 and methods for generating and processing Thread Network Layer TLVs.
32  */
33 
34 #ifndef THREAD_TLVS_HPP_
35 #define THREAD_TLVS_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include "common/encoding.hpp"
40 #include "common/message.hpp"
41 #include "common/tlvs.hpp"
42 #include "meshcop/network_name.hpp"
43 #include "net/ip6_address.hpp"
44 #include "thread/mle.hpp"
45 #include "thread/mle_types.hpp"
46 
47 namespace ot {
48 
49 /**
50  * Implements Network Layer TLV generation and parsing.
51  *
52  */
53 OT_TOOL_PACKED_BEGIN
54 class ThreadTlv : public ot::Tlv
55 {
56 public:
57     /**
58      * Network Layer TLV Types.
59      *
60      */
61     enum Type : uint8_t
62     {
63         kTarget                = 0,  ///< Target EID TLV
64         kExtMacAddress         = 1,  ///< Extended MAC Address TLV
65         kRloc16                = 2,  ///< RLOC16 TLV
66         kMeshLocalEid          = 3,  ///< ML-EID TLV
67         kStatus                = 4,  ///< Status TLV
68         kLastTransactionTime   = 6,  ///< Time Since Last Transaction TLV
69         kRouterMask            = 7,  ///< Router Mask TLV
70         kNdOption              = 8,  ///< ND Option TLV
71         kNdData                = 9,  ///< ND Data TLV
72         kThreadNetworkData     = 10, ///< Thread Network Data TLV
73         kTimeout               = 11, ///< Timeout TLV
74         kNetworkName           = 12, ///< Network Name TLV
75         kIp6Addresses          = 14, ///< IPv6 Addresses TLV
76         kCommissionerSessionId = 15, ///< Commissioner Session ID TLV
77     };
78 
79     /**
80      * Returns the Type value.
81      *
82      * @returns The Type value.
83      *
84      */
GetType(void) const85     Type GetType(void) const { return static_cast<Type>(ot::Tlv::GetType()); }
86 
87     /**
88      * Sets the Type value.
89      *
90      * @param[in]  aType  The Type value.
91      *
92      */
SetType(Type aType)93     void SetType(Type aType) { ot::Tlv::SetType(static_cast<uint8_t>(aType)); }
94 
95 } OT_TOOL_PACKED_END;
96 
97 /**
98  * Defines Target TLV constants and types.
99  *
100  */
101 typedef SimpleTlvInfo<ThreadTlv::kTarget, Ip6::Address> ThreadTargetTlv;
102 
103 /**
104  * Defines Extended MAC Address TLV constants and types.
105  *
106  */
107 typedef SimpleTlvInfo<ThreadTlv::kExtMacAddress, Mac::ExtAddress> ThreadExtMacAddressTlv;
108 
109 /**
110  * Defines RLOC16 TLV constants and types.
111  *
112  */
113 typedef UintTlvInfo<ThreadTlv::kRloc16, uint16_t> ThreadRloc16Tlv;
114 
115 /**
116  * Defines ML-EID TLV constants and types.
117  *
118  */
119 typedef SimpleTlvInfo<ThreadTlv::kMeshLocalEid, Ip6::InterfaceIdentifier> ThreadMeshLocalEidTlv;
120 
121 /**
122  * Defines Time Since Last Transaction TLV constants and types.
123  *
124  */
125 typedef UintTlvInfo<ThreadTlv::kLastTransactionTime, uint32_t> ThreadLastTransactionTimeTlv;
126 
127 /**
128  * Defines Timeout TLV constants and types.
129  *
130  */
131 typedef UintTlvInfo<ThreadTlv::kTimeout, uint32_t> ThreadTimeoutTlv;
132 
133 /**
134  * Defines Network Name TLV constants and types.
135  *
136  */
137 typedef StringTlvInfo<ThreadTlv::kNetworkName, MeshCoP::NetworkName::kMaxSize> ThreadNetworkNameTlv;
138 
139 /**
140  * Defines Commissioner Session ID TLV constants and types.
141  *
142  */
143 typedef UintTlvInfo<ThreadTlv::kCommissionerSessionId, uint16_t> ThreadCommissionerSessionIdTlv;
144 
145 /**
146  * Defines Status TLV constants and types.
147  *
148  */
149 class ThreadStatusTlv : public UintTlvInfo<ThreadTlv::kStatus, uint8_t>
150 {
151 public:
152     /**
153      * Status values.
154      *
155      */
156     enum Status : uint8_t
157     {
158         kSuccess               = 0, ///< Success.
159         kNoAddressAvailable    = 1, ///< No address available.
160         kTooFewRouters         = 2, ///< Address Solicit due to too few routers.
161         kHaveChildIdRequest    = 3, ///< Address Solicit due to child ID request.
162         kParentPartitionChange = 4, ///< Address Solicit due to parent partition change
163         kBorderRouterRequest   = 5, ///< Address Solicit from Border Router request.
164         kUnrecognizedStatus    = 6, ///< The requested status is unrecognized or not meaningful in a request.
165     };
166 
167     /**
168      * Multicast Listener Registration (MLR) Status values
169      *
170      */
171     enum MlrStatus
172     {
173         kMlrSuccess        = 0, ///< Successful (de)registration of all IPv6 addresses.
174         kMlrInvalid        = 2, ///< Invalid IPv6 address(es) in request.
175         kMlrNoPersistent   = 3, ///< This device does not support persistent registrations.
176         kMlrNoResources    = 4, ///< BBR resource shortage.
177         kMlrBbrNotPrimary  = 5, ///< BBR is not Primary at this moment.
178         kMlrGeneralFailure = 6, ///< Reason(s) for failure are not further specified.
179         kMlrStatusMax      = 6, ///< Max MLR status.
180     };
181 
182     /**
183      * Domain Unicast Address (DUA) Registration Status values
184      *
185      */
186     enum DuaStatus : uint8_t
187     {
188         kDuaSuccess        = 0, ///< Successful registration.
189         kDuaReRegister     = 1, ///< Registration was accepted but immediate reregistration is required to solve.
190         kDuaInvalid        = 2, ///< Registration rejected (Fatal): Target EID is not a valid DUA.
191         kDuaDuplicate      = 3, ///< Registration rejected (Fatal): DUA is already in use by another device.
192         kDuaNoResources    = 4, ///< Registration rejected (Non-fatal): Backbone Router Resource shortage.
193         kDuaNotPrimary     = 5, ///< Registration rejected (Non-fatal): Backbone Router is not primary at this moment.
194         kDuaGeneralFailure = 6, ///< Registration failure (Non-fatal): Reason(s) not further specified.
195     };
196 };
197 
198 /**
199  * Implements Router Mask TLV generation and parsing.
200  *
201  */
202 class ThreadRouterMaskTlv : public ThreadTlv, public TlvInfo<ThreadTlv::kRouterMask>
203 {
204 public:
205     /**
206      * Initializes the TLV.
207      *
208      */
Init(void)209     void Init(void)
210     {
211         SetType(kRouterMask);
212         SetLength(sizeof(*this) - sizeof(ThreadTlv));
213         mAssignedRouterIdMask.Clear();
214     }
215 
216     /**
217      * Indicates whether or not the TLV appears to be well-formed.
218      *
219      * @retval TRUE   If the TLV appears to be well-formed.
220      * @retval FALSE  If the TLV does not appear to be well-formed.
221      *
222      */
IsValid(void) const223     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(ThreadTlv); }
224 
225     /**
226      * Returns the ID Sequence value.
227      *
228      * @returns The ID Sequence value.
229      *
230      */
GetIdSequence(void) const231     uint8_t GetIdSequence(void) const { return mIdSequence; }
232 
233     /**
234      * Sets the ID Sequence value.
235      *
236      * @param[in]  aSequence  The ID Sequence value.
237      *
238      */
SetIdSequence(uint8_t aSequence)239     void SetIdSequence(uint8_t aSequence) { mIdSequence = aSequence; }
240 
241     /**
242      * Gets the Assigned Router ID Mask.
243      *
244      * @returns The Assigned Router ID Mask.
245      *
246      */
GetAssignedRouterIdMask(void) const247     const Mle::RouterIdSet &GetAssignedRouterIdMask(void) const { return mAssignedRouterIdMask; }
248 
249     /**
250      * Gets the Assigned Router ID Mask.
251      *
252      * @returns The Assigned Router ID Mask.
253      *
254      */
GetAssignedRouterIdMask(void)255     Mle::RouterIdSet &GetAssignedRouterIdMask(void) { return mAssignedRouterIdMask; }
256 
257     /**
258      * Sets the Assigned Router ID Mask.
259      *
260      * @param[in]  aRouterIdSet A reference to the Assigned Router ID Mask.
261      *
262      */
SetAssignedRouterIdMask(const Mle::RouterIdSet & aRouterIdSet)263     void SetAssignedRouterIdMask(const Mle::RouterIdSet &aRouterIdSet) { mAssignedRouterIdMask = aRouterIdSet; }
264 
265 private:
266     uint8_t          mIdSequence;
267     Mle::RouterIdSet mAssignedRouterIdMask;
268 };
269 
270 /**
271  * Implements Thread Network Data TLV generation and parsing.
272  *
273  */
274 OT_TOOL_PACKED_BEGIN
275 class ThreadNetworkDataTlv : public ThreadTlv, public TlvInfo<ThreadTlv::kThreadNetworkData>
276 {
277 public:
278     /**
279      * Initializes the TLV.
280      *
281      */
Init(void)282     void Init(void)
283     {
284         SetType(kThreadNetworkData);
285         SetLength(0);
286     }
287 
288     /**
289      * Overrides same method of the base class
290      *
291      * @retval TRUE  the TLV appears to be well-formed.
292      *
293      */
IsValid(void) const294     bool IsValid(void) const { return true; }
295 
296     /**
297      * Returns a pointer to the Network Data TLVs.
298      *
299      * @returns A pointer to the Network Data TLVs.
300      *
301      */
GetTlvs(void)302     uint8_t *GetTlvs(void) { return mTlvs; }
303 
304 private:
305     static constexpr uint8_t kMaxSize = 255;
306 
307     uint8_t mTlvs[kMaxSize];
308 } OT_TOOL_PACKED_END;
309 
310 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
311 
312 /**
313  * Implements IPv6 Addresses TLV generation and parsing.
314  *
315  */
316 OT_TOOL_PACKED_BEGIN
317 class Ip6AddressesTlv : public ThreadTlv, public TlvInfo<ThreadTlv::kIp6Addresses>
318 {
319 public:
320     // Thread 1.2.0 5.19.13 limits the number of IPv6 addresses to [1, 15].
321     static constexpr uint8_t kMinAddresses = 1;
322     static constexpr uint8_t kMaxAddresses = OT_IP6_MAX_MLR_ADDRESSES;
323 
324     /**
325      * Initializes the TLV.
326      *
327      */
Init(void)328     void Init(void) { SetType(kIp6Addresses); }
329 
330     /**
331      * Indicates whether or not the TLV appears to be well-formed.
332      *
333      * @retval TRUE   If the TLV appears to be well-formed.
334      * @retval FALSE  If the TLV does not appear to be well-formed.
335      *
336      */
IsValid(void) const337     bool IsValid(void) const
338     {
339         return GetLength() >= sizeof(Ip6::Address) * Ip6AddressesTlv::kMinAddresses &&
340                GetLength() <= sizeof(Ip6::Address) * Ip6AddressesTlv::kMaxAddresses &&
341                (GetLength() % sizeof(Ip6::Address)) == 0;
342     }
343 
344     /**
345      * Returns a pointer to the IPv6 address entry.
346      *
347      * @param[in]  aIndex  The index into the IPv6 address list.
348      *
349      * @returns A reference to the IPv6 address.
350      *
351      */
GetIp6Address(uint8_t aIndex) const352     const Ip6::Address &GetIp6Address(uint8_t aIndex) const
353     {
354         return *reinterpret_cast<const Ip6::Address *>(GetValue() + (aIndex * sizeof(Ip6::Address)));
355     }
356 } OT_TOOL_PACKED_END;
357 
358 #endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
359 
360 } // namespace ot
361 
362 #endif // THREAD_TLVS_HPP_
363