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 #ifndef TEST_LOWPAN_HPP
30 #define TEST_LOWPAN_HPP
31 
32 #include <stdint.h>
33 
34 #include "common/code_utils.hpp"
35 #include "instance/instance.hpp"
36 #include "mac/mac.hpp"
37 #include "net/ip6_headers.hpp"
38 #include "thread/lowpan.hpp"
39 #include "thread/thread_netif.hpp"
40 
41 namespace ot {
42 
43 class TestIphcVector
44 {
45 public:
46     enum
47     {
48         kContextUnused    = 255,
49         kPayloadMaxLength = 512
50     };
51 
52     struct Payload
53     {
54         uint8_t  mData[kPayloadMaxLength];
55         uint16_t mLength;
56     };
57 
58     /**
59      * Default constructor for the object.
60      *
61      */
TestIphcVector(const char * aTestName)62     explicit TestIphcVector(const char *aTestName)
63     {
64         memset(reinterpret_cast<void *>(this), 0, sizeof(TestIphcVector));
65         mTestName              = aTestName;
66         mSrcContext.mContextId = kContextUnused;
67         mDstContext.mContextId = kContextUnused;
68     }
69 
70     /**
71      * Sets long MAC source address.
72      *
73      * @param aAddress Pointer to the long MAC address.
74      *
75      */
SetMacSource(const uint8_t * aAddress)76     void SetMacSource(const uint8_t *aAddress) { mMacAddrs.mSource.SetExtended(aAddress); }
77 
78     /**
79      * Sets short MAC source address.
80      *
81      * @param aAddress Short MAC address.
82      *
83      */
SetMacSource(uint16_t aAddress)84     void SetMacSource(uint16_t aAddress) { mMacAddrs.mSource.SetShort(aAddress); }
85 
86     /**
87      * Sets long MAC destination address.
88      *
89      * @param aAddress Pointer to the long MAC address.
90      *
91      */
SetMacDestination(const uint8_t * aAddress)92     void SetMacDestination(const uint8_t *aAddress) { mMacAddrs.mDestination.SetExtended(aAddress); }
93 
94     /**
95      * Sets short MAC destination address.
96      *
97      * @param aAddress Short MAC address.
98      *
99      */
SetMacDestination(uint16_t aAddress)100     void SetMacDestination(uint16_t aAddress) { mMacAddrs.mDestination.SetShort(aAddress); }
101 
102     /**
103      * Gets the IPv6 header
104      *
105      * @returns the IPv6 header.
106      *
107      */
GetIpHeader(void) const108     const Ip6::Header &GetIpHeader(void) const { return mIpHeader; }
109 
110     /**
111      * Initializes IPv6 Header.
112      *
113      * @param aVersionClassFlow Value of the Version, Traffic class and Flow control fields.
114      * @param aPayloadLength    Value of the payload length field.
115      * @param aNextHeader       Value of the next header field.
116      * @param aHopLimit         Value of the hop limit field.
117      * @param aSource           String represents IPv6 source address.
118      * @param aDestination      String represents IPv6 destination address.
119      *
120      */
SetIpHeader(uint32_t aVersionClassFlow,uint16_t aPayloadLength,uint8_t aNextHeader,uint8_t aHopLimit,const char * aSource,const char * aDestination)121     void SetIpHeader(uint32_t    aVersionClassFlow,
122                      uint16_t    aPayloadLength,
123                      uint8_t     aNextHeader,
124                      uint8_t     aHopLimit,
125                      const char *aSource,
126                      const char *aDestination)
127     {
128         mIpHeader.SetVerionTrafficClassFlow(aVersionClassFlow);
129         mIpHeader.SetPayloadLength(aPayloadLength);
130         mIpHeader.SetNextHeader(aNextHeader);
131         mIpHeader.SetHopLimit(aHopLimit);
132         IgnoreError(mIpHeader.GetSource().FromString(aSource));
133         IgnoreError(mIpHeader.GetDestination().FromString(aDestination));
134     }
135 
136     /**
137      * Initializes IPv6 Encapsulated Header.
138      *
139      * @param aVersionClassFlow Value of the Version, Traffic class and Flow control fields.
140      * @param aPayloadLength    Value of the payload length field.
141      * @param aNextHeader       Value of the next header field.
142      * @param aHopLimit         Value of the hop limit field.
143      * @param aSource           String represents IPv6 source address.
144      * @param aDestination      String represents IPv6 destination address.
145      *
146      */
SetIpTunneledHeader(uint32_t aVersionClassFlow,uint16_t aPayloadLength,uint8_t aNextHeader,uint8_t aHopLimit,const char * aSource,const char * aDestination)147     void SetIpTunneledHeader(uint32_t    aVersionClassFlow,
148                              uint16_t    aPayloadLength,
149                              uint8_t     aNextHeader,
150                              uint8_t     aHopLimit,
151                              const char *aSource,
152                              const char *aDestination)
153     {
154         mIpTunneledHeader.SetVerionTrafficClassFlow(aVersionClassFlow);
155         mIpTunneledHeader.SetPayloadLength(aPayloadLength);
156         mIpTunneledHeader.SetNextHeader(aNextHeader);
157         mIpTunneledHeader.SetHopLimit(aHopLimit);
158         IgnoreError(mIpTunneledHeader.GetSource().FromString(aSource));
159         IgnoreError(mIpTunneledHeader.GetDestination().FromString(aDestination));
160     }
161 
162     /**
163      * Initializes IPv6 Extension Header.
164      *
165      * @param aExtHeader        Pointer to the extension header data.
166      * @param aExtHeaderLength  Length of the extension header data.
167      *
168      */
SetExtHeader(const uint8_t * aExtHeader,uint16_t aExtHeaderLength)169     void SetExtHeader(const uint8_t *aExtHeader, uint16_t aExtHeaderLength)
170     {
171         memcpy(mExtHeader.mData, aExtHeader, aExtHeaderLength);
172         mExtHeader.mLength = aExtHeaderLength;
173     }
174 
175     /**
176      * Initializes UDP Header.
177      *
178      * @param aSource       Value of the source port.
179      * @param aDestination  Value of the destination port.
180      * @param aLength       Value of the length field.
181      * @param aChecksum     Value of the checksum field.
182      *
183      */
SetUDPHeader(uint16_t aSource,uint16_t aDestination,uint16_t aLength,uint16_t aChecksum)184     void SetUDPHeader(uint16_t aSource, uint16_t aDestination, uint16_t aLength, uint16_t aChecksum)
185     {
186         mUdpHeader.SetSourcePort(aSource);
187         mUdpHeader.SetDestinationPort(aDestination);
188         mUdpHeader.SetLength(aLength);
189         mUdpHeader.SetChecksum(aChecksum);
190     }
191 
192     /**
193      * Initializes LOWPAN_IPHC Header.
194      *
195      * @param aIphc        Pointer to the LOWPAN_IPHC header.
196      * @param aIphcLength  Length of the LOWPAN_IPHC header.
197      *
198      */
SetIphcHeader(const uint8_t * aIphc,uint16_t aIphcLength)199     void SetIphcHeader(const uint8_t *aIphc, uint16_t aIphcLength)
200     {
201         memcpy(mIphcHeader.mData, aIphc, aIphcLength);
202         mIphcHeader.mLength = aIphcLength;
203     }
204 
205     /**
206      * Sets the expect result of the compression / decompression procedure.
207      *
208      * @param aError  Expected result.
209      *
210      */
SetError(Error aError)211     void SetError(Error aError) { mError = aError; }
212 
213     /**
214      * Initializes IPv6 Payload (uncompressed data).
215      *
216      * @param aPayload  Pointer to the payload data.
217      * @param aLength   Length of the payload data.
218      *
219      */
SetPayload(const uint8_t * aPayload,uint16_t aLength)220     void SetPayload(const uint8_t *aPayload, uint16_t aLength)
221     {
222         memcpy(mPayload.mData, aPayload, aLength);
223         mPayload.mLength = aLength;
224     }
225 
226     /**
227      * Sets the offset from the beginning of the IPv6 header to the uncompressed
228      * payload.
229      *
230      * @param aPayloadOffset  The offset from the beginning of the IPv6 header to the uncompressed
231      *                        payload.
232      *
233      */
SetPayloadOffset(uint16_t aPayloadOffset)234     void SetPayloadOffset(uint16_t aPayloadOffset) { mPayloadOffset = aPayloadOffset; }
235 
236     /**
237      * Returns compressed LOWPAN_IPHC frame.
238      *
239      * @returns The compressed stream.
240      *
241      */
242     void GetCompressedStream(uint8_t *aIphc, uint16_t &aIphcLength);
243 
244     /**
245      * Returns message object with the uncompressed IPv6 packet.
246      *
247      * @returns The message object with the uncompressed IPv6 packet.
248      *
249      */
250     void GetUncompressedStream(Message &aMessage);
251 
252     /**
253      * Returns data with the uncompressed IPv6 packet.
254      *
255      * @returns The data with the uncompressed IPv6 packet.
256      *
257      */
258     void GetUncompressedStream(uint8_t *aIp6, uint16_t &aIp6Length);
259 
260     /**
261      * This fields represent uncompressed IPv6 packet.
262      *
263      */
264     Mac::Addresses   mMacAddrs;
265     Ip6::Header      mIpHeader;
266     Payload          mExtHeader;
267     Ip6::Header      mIpTunneledHeader;
268     Ip6::Udp::Header mUdpHeader;
269 
270     /**
271      * This fields represent compressed IPv6 packet.
272      *
273      */
274     Payload         mIphcHeader;
275     uint16_t        mPayloadOffset;
276     Lowpan::Context mSrcContext;
277     Lowpan::Context mDstContext;
278 
279     /**
280      * General purpose fields.
281      *
282      */
283     Payload     mPayload;
284     Error       mError;
285     const char *mTestName;
286 };
287 
288 } // namespace ot
289 
290 #endif // TEST_LOWPAN_HPP
291