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