• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "test_lowpan.hpp"
30 
31 #include "test_platform.h"
32 #include "test_util.hpp"
33 
34 namespace ot {
35 
36 Instance       *sInstance;
37 Ip6::Ip6       *sIp6;
38 Lowpan::Lowpan *sLowpan;
39 
GetCompressedStream(uint8_t * aIphc,uint16_t & aIphcLength)40 void TestIphcVector::GetCompressedStream(uint8_t *aIphc, uint16_t &aIphcLength)
41 {
42     memcpy(aIphc, mIphcHeader.mData, mIphcHeader.mLength);
43     memcpy(aIphc + mIphcHeader.mLength, mPayload.mData, mPayload.mLength);
44 
45     aIphcLength = mIphcHeader.mLength + mPayload.mLength;
46 }
47 
GetUncompressedStream(uint8_t * aIp6,uint16_t & aIp6Length)48 void TestIphcVector::GetUncompressedStream(uint8_t *aIp6, uint16_t &aIp6Length)
49 {
50     aIp6Length = 0;
51 
52     memcpy(aIp6, reinterpret_cast<uint8_t *>(&mIpHeader), sizeof(mIpHeader));
53     aIp6Length += sizeof(mIpHeader);
54 
55     if (mExtHeader.mLength)
56     {
57         memcpy(aIp6 + aIp6Length, mExtHeader.mData, mExtHeader.mLength);
58         aIp6Length += mExtHeader.mLength;
59     }
60 
61     if (mIpTunneledHeader.GetPayloadLength())
62     {
63         memcpy(aIp6 + aIp6Length, reinterpret_cast<uint8_t *>(&mIpTunneledHeader), sizeof(mIpTunneledHeader));
64         aIp6Length += sizeof(mIpTunneledHeader);
65     }
66 
67     if (mUdpHeader.GetLength())
68     {
69         memcpy(aIp6 + aIp6Length, reinterpret_cast<uint8_t *>(&mUdpHeader), sizeof(mUdpHeader));
70         aIp6Length += sizeof(mUdpHeader);
71     }
72 
73     memcpy(aIp6 + aIp6Length, mPayload.mData, mPayload.mLength);
74     aIp6Length += mPayload.mLength;
75 }
76 
GetUncompressedStream(Message & aMessage)77 void TestIphcVector::GetUncompressedStream(Message &aMessage)
78 {
79     SuccessOrQuit(aMessage.Append(mIpHeader));
80 
81     if (mExtHeader.mLength)
82     {
83         SuccessOrQuit(aMessage.AppendBytes(mExtHeader.mData, mExtHeader.mLength));
84     }
85 
86     if (mIpTunneledHeader.GetPayloadLength())
87     {
88         SuccessOrQuit(aMessage.Append(mIpTunneledHeader));
89     }
90 
91     if (mUdpHeader.GetLength())
92     {
93         SuccessOrQuit(aMessage.Append(mUdpHeader));
94     }
95 
96     SuccessOrQuit(aMessage.AppendBytes(mPayload.mData, mPayload.mLength));
97 }
98 
99 /**
100  * Initializes Thread Interface.
101  *
102  */
Init(void)103 static void Init(void)
104 {
105     otMeshLocalPrefix meshLocalPrefix = {{0xfd, 0x00, 0xca, 0xfe, 0xfa, 0xce, 0x12, 0x34}};
106 
107     sInstance->Get<Mle::MleRouter>().SetMeshLocalPrefix(static_cast<Ip6::NetworkPrefix &>(meshLocalPrefix));
108 
109     // Emulate global prefixes with contextes.
110     uint8_t mockNetworkData[] = {
111         0x0c, // MLE Network Data Type
112         0x20, // MLE Network Data Length
113 
114         // Prefix 2001:2:0:1::/64
115         0x03, 0x0e,                                                             // Prefix TLV
116         0x00, 0x40, 0x20, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x07, 0x02, // 6LoWPAN Context ID TLV
117         0x11, 0x40,                                                             // Context ID = 1, C = TRUE
118 
119         // Prefix 2001:2:0:2::/64
120         0x03, 0x0e,                                                             // Prefix TLV
121         0x00, 0x40, 0x20, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x07, 0x02, // 6LoWPAN Context ID TLV
122         0x02, 0x40                                                              // Context ID = 2, C = FALSE
123     };
124 
125     Message *message = sInstance->Get<MessagePool>().Allocate(Message::kTypeIp6);
126     VerifyOrQuit(message != nullptr, "Ip6::NewMessage failed");
127 
128     SuccessOrQuit(message->AppendBytes(mockNetworkData, sizeof(mockNetworkData)));
129 
130     IgnoreError(
131         sInstance->Get<NetworkData::Leader>().SetNetworkData(0, 0, NetworkData::kStableSubset, *message, 2, 0x20));
132 }
133 
134 /**
135  * Performs compression or/and decompression based on the given test vector.
136  *
137  * @note Performing decompression and compression on the same LOWPAN_IPHC frame may give different result.
138  *       This situation may occur when sender does not use the best possible compression,
139  *       e.g. doesn't use LOWPAN_NHC for UDP - which is still valid.
140  *
141  * @param aVector     Test vector that has to be tested.
142  * @param aCompress   Set to TRUE, if compression should be tested.
143  * @param aDecompress Set to TRUE, if decomrpession should be tested.
144  */
Test(TestIphcVector & aVector,bool aCompress,bool aDecompress)145 static void Test(TestIphcVector &aVector, bool aCompress, bool aDecompress)
146 {
147     Message  *message = nullptr;
148     uint8_t   result[512];
149     uint8_t   iphc[512];
150     uint8_t   ip6[512];
151     uint16_t  iphcLength;
152     uint16_t  ip6Length;
153     FrameData frameData;
154     Error     error;
155 
156     aVector.GetCompressedStream(iphc, iphcLength);
157     aVector.GetUncompressedStream(ip6, ip6Length);
158 
159     printf("\n=== Test name: %s ===\n\n", aVector.mTestName);
160 
161     printf("Expected error -------------- %s\n", aVector.mError ? "yes" : "no");
162     printf("UDP present ----------------- %s\n", aVector.mUdpHeader.GetLength() ? "yes" : "no");
163     printf("Extension Headers present --- %s\n", aVector.mExtHeader.mLength ? "yes" : "no");
164     printf("IP-in-IP present ------------ %s\n", aVector.mIpTunneledHeader.GetPayloadLength() ? "yes" : "no");
165     printf("LOWPAN_IPHC length ---------- %d\n", aVector.mIphcHeader.mLength);
166     printf("IPv6 uncompressed offset ---- %d\n\n", aVector.mPayloadOffset);
167 
168     DumpBuffer("Expected IPv6 uncompressed packet", ip6, ip6Length);
169     DumpBuffer("Expected LOWPAN_IPHC compressed frame", iphc, iphcLength);
170 
171     if (aCompress)
172     {
173         FrameBuilder frameBuilder;
174         Message     *compressedMsg;
175         Ip6::Ecn     ecn;
176 
177         frameBuilder.Init(result, 127);
178 
179         VerifyOrQuit((message = sInstance->Get<MessagePool>().Allocate(Message::kTypeIp6)) != nullptr);
180 
181         aVector.GetUncompressedStream(*message);
182 
183         VerifyOrQuit(sLowpan->Compress(*message, aVector.mMacAddrs, frameBuilder) == aVector.mError);
184 
185         if (aVector.mError == kErrorNone)
186         {
187             uint16_t compressBytes = frameBuilder.GetLength();
188 
189             // Append payload to the LOWPAN_IPHC.
190             message->ReadBytes(message->GetOffset(), result + compressBytes,
191                                message->GetLength() - message->GetOffset());
192 
193             DumpBuffer("Resulted LOWPAN_IPHC compressed frame", result,
194                        compressBytes + message->GetLength() - message->GetOffset());
195 
196             VerifyOrQuit(compressBytes == aVector.mIphcHeader.mLength, "Lowpan::Compress failed");
197             VerifyOrQuit(message->GetOffset() == aVector.mPayloadOffset, "Lowpan::Compress failed");
198             VerifyOrQuit(memcmp(iphc, result, iphcLength) == 0, "Lowpan::Compress failed");
199 
200             // Validate `DecompressEcn()` and `MarkCompressedEcn()`
201 
202             VerifyOrQuit((compressedMsg = sInstance->Get<MessagePool>().Allocate(Message::kTypeIp6)) != nullptr);
203             SuccessOrQuit(compressedMsg->AppendBytes(result, compressBytes));
204 
205             ecn = sLowpan->DecompressEcn(*compressedMsg, /* aOffset */ 0);
206             VerifyOrQuit(ecn == aVector.GetIpHeader().GetEcn());
207             printf("Decompressed ECN is %d\n", ecn);
208 
209             if (ecn != Ip6::kEcnNotCapable)
210             {
211                 sLowpan->MarkCompressedEcn(*compressedMsg, /*a aOffset */ 0);
212                 ecn = sLowpan->DecompressEcn(*compressedMsg, /* aOffset */ 0);
213                 VerifyOrQuit(ecn == Ip6::kEcnMarked);
214                 printf("ECN is updated to %d\n", ecn);
215             }
216 
217             compressedMsg->Free();
218         }
219 
220         message->Free();
221         message = nullptr;
222     }
223 
224     if (aDecompress)
225     {
226         VerifyOrQuit((message = sInstance->Get<MessagePool>().Allocate(Message::kTypeIp6)) != nullptr);
227 
228         frameData.Init(iphc, iphcLength);
229 
230         error = sLowpan->Decompress(*message, aVector.mMacAddrs, frameData, 0);
231 
232         message->ReadBytes(0, result, message->GetLength());
233 
234         if (aVector.mError == kErrorNone)
235         {
236             SuccessOrQuit(error, "Lowpan::Decompress failed");
237 
238             // Append payload to the IPv6 Packet.
239             memcpy(result + message->GetLength(), frameData.GetBytes(), frameData.GetLength());
240 
241             DumpBuffer("Resulted IPv6 uncompressed packet", result, message->GetLength() + frameData.GetLength());
242 
243             VerifyOrQuit((frameData.GetBytes() - iphc) == aVector.mIphcHeader.mLength, "Lowpan::Decompress failed");
244             VerifyOrQuit(message->GetOffset() == aVector.mPayloadOffset, "Lowpan::Decompress failed");
245             VerifyOrQuit(message->GetOffset() == message->GetLength(), "Lowpan::Decompress failed");
246             VerifyOrQuit(memcmp(ip6, result, ip6Length) == 0, "Lowpan::Decompress failed");
247         }
248         else
249         {
250             VerifyOrQuit(error == kErrorParse, "Lowpan::Decompress failed");
251         }
252 
253         message->Free();
254         message = nullptr;
255     }
256 
257     printf("PASS\n\n");
258 }
259 
260 /***************************************************************************************************
261  * @section Test constants.
262  **************************************************************************************************/
263 static const uint8_t sTestMacSourceDefaultLong[]      = {0x00, 0x00, 0x5e, 0xef, 0x10, 0x22, 0x11, 0x00};
264 static const uint8_t sTestMacDestinationDefaultLong[] = {0x00, 0x00, 0x5e, 0xef, 0x10, 0xaa, 0xbb, 0xcc};
265 
266 static uint16_t sTestMacSourceDefaultShort      = 0x0000;
267 static uint16_t sTestMacDestinationDefaultShort = 0xc003;
268 static uint16_t sTestMacDestinationBroadcast    = 0xffff;
269 
270 static const uint8_t sTestPayloadDefault[] = {0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
271 
272 /***************************************************************************************************
273  * @section Test cases.
274  **************************************************************************************************/
275 
TestFullyCompressableLongAddresses(void)276 static void TestFullyCompressableLongAddresses(void)
277 {
278     TestIphcVector testVector("Fully compressible IPv6 addresses using long MAC addresses");
279 
280     // Setup MAC addresses.
281     testVector.SetMacSource(sTestMacSourceDefaultLong);
282     testVector.SetMacDestination(sTestMacDestinationDefaultLong);
283 
284     // Setup IPv6 header.
285     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1100",
286                            "fe80::200:5eef:10aa:bbcc");
287 
288     // Set LOWPAN_IPHC header.
289     uint8_t iphc[] = {0x7a, 0x33, 0x3a};
290     testVector.SetIphcHeader(iphc, sizeof(iphc));
291 
292     // Set payload and error.
293     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
294     testVector.SetPayloadOffset(40);
295     testVector.SetError(kErrorNone);
296 
297     // Perform compression and decompression tests.
298     Test(testVector, true, true);
299 }
300 
TestFullyCompressableShortAddresses(void)301 static void TestFullyCompressableShortAddresses(void)
302 {
303     TestIphcVector testVector("Fully compressible IPv6 addresses using short MAC addresses");
304 
305     // Setup MAC addresses.
306     testVector.SetMacSource(sTestMacSourceDefaultShort);
307     testVector.SetMacDestination(sTestMacDestinationDefaultShort);
308 
309     // Setup IPv6 header.
310     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::ff:fe00:0000",
311                            "fe80::ff:fe00:c003");
312 
313     // Set LOWPAN_IPHC header.
314     uint8_t iphc[] = {0x7a, 0x33, 0x3a};
315     testVector.SetIphcHeader(iphc, sizeof(iphc));
316 
317     // Set payload and error.
318     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
319     testVector.SetPayloadOffset(40);
320     testVector.SetError(kErrorNone);
321 
322     // Perform compression and decompression tests.
323     Test(testVector, true, true);
324 }
325 
TestFullyCompressableShortLongAddresses(void)326 static void TestFullyCompressableShortLongAddresses(void)
327 {
328     TestIphcVector testVector("Fully compressible IPv6 addresses using short and long MAC addresses");
329 
330     // Setup MAC addresses.
331     testVector.SetMacSource(sTestMacSourceDefaultShort);
332     testVector.SetMacDestination(sTestMacDestinationDefaultLong);
333 
334     // Setup IPv6 header.
335     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::ff:fe00:0000",
336                            "fe80::200:5eef:10aa:bbcc");
337 
338     // Set LOWPAN_IPHC header.
339     uint8_t iphc[] = {0x7a, 0x33, 0x3a};
340     testVector.SetIphcHeader(iphc, sizeof(iphc));
341 
342     // Set payload and error.
343     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
344     testVector.SetPayloadOffset(40);
345     testVector.SetError(kErrorNone);
346 
347     // Perform compression and decompression tests.
348     Test(testVector, true, true);
349 }
350 
TestFullyCompressableLongShortAddresses(void)351 static void TestFullyCompressableLongShortAddresses(void)
352 {
353     TestIphcVector testVector("Fully compressible IPv6 addresses using long and short MAC addresses");
354 
355     // Setup MAC addresses.
356     testVector.SetMacSource(sTestMacSourceDefaultLong);
357     testVector.SetMacDestination(sTestMacDestinationDefaultShort);
358 
359     // Setup IPv6 header.
360     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1100",
361                            "fe80::ff:fe00:c003");
362 
363     // Set LOWPAN_IPHC header.
364     uint8_t iphc[] = {0x7a, 0x33, 0x3a};
365     testVector.SetIphcHeader(iphc, sizeof(iphc));
366 
367     // Set payload and error.
368     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
369     testVector.SetPayloadOffset(40);
370     testVector.SetError(kErrorNone);
371 
372     // Perform compression and decompression tests.
373     Test(testVector, true, true);
374 }
375 
TestSourceUnspecifiedAddress(void)376 static void TestSourceUnspecifiedAddress(void)
377 {
378     TestIphcVector testVector("Unspecified source IPv6 address");
379 
380     // Setup MAC addresses.
381     testVector.SetMacSource(sTestMacSourceDefaultLong);
382     testVector.SetMacDestination(sTestMacDestinationDefaultShort);
383 
384     // Setup IPv6 header.
385     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "::", "fe80::ff:fe00:c003");
386 
387     // Set LOWPAN_IPHC header.
388     uint8_t iphc[] = {0x7a, 0x43, 0x3a};
389     testVector.SetIphcHeader(iphc, sizeof(iphc));
390 
391     // Set payload and error.
392     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
393     testVector.SetPayloadOffset(40);
394     testVector.SetError(kErrorNone);
395 
396     // Perform compression and decompression tests.
397     Test(testVector, true, true);
398 }
399 
TestSource128bitDestination128bitAddresses(void)400 static void TestSource128bitDestination128bitAddresses(void)
401 {
402     TestIphcVector testVector("IPv6 addresses inline");
403 
404     // Setup MAC addresses.
405     testVector.SetMacSource(sTestMacSourceDefaultLong);
406     testVector.SetMacDestination(sTestMacDestinationDefaultShort);
407 
408     // Setup IPv6 header.
409     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64,
410                            "2001:2:0:3:aaaa:bbbb:cccc:dddd", "2001:2:0:4::");
411 
412     // Set LOWPAN_IPHC header.
413     uint8_t iphc[] = {0x7a, 0x00, 0x3a, 0x20, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0xaa,
414                       0xaa, 0xbb, 0xbb, 0xcc, 0xcc, 0xdd, 0xdd, 0x20, 0x01, 0x00, 0x02, 0x00,
415                       0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
416     testVector.SetIphcHeader(iphc, sizeof(iphc));
417 
418     // Set payload and error.
419     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
420     testVector.SetPayloadOffset(40);
421     testVector.SetError(kErrorNone);
422 
423     // Perform compression and decompression tests.
424     Test(testVector, true, true);
425 }
426 
TestSource64bitDestination64bitLongAddresses(void)427 static void TestSource64bitDestination64bitLongAddresses(void)
428 {
429     TestIphcVector testVector("IPv6 addresses 64-bit using long MAC addresses");
430 
431     // Setup MAC addresses.
432     testVector.SetMacSource(sTestMacSourceDefaultLong);
433     testVector.SetMacDestination(sTestMacDestinationDefaultLong);
434 
435     // Setup IPv6 header.
436     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1101",
437                            "fe80::200:5eef:10aa:bbcd");
438 
439     // Set LOWPAN_IPHC header.
440     uint8_t iphc[] = {0x7a, 0x11, 0x3a, 0x02, 0x00, 0x5e, 0xef, 0x10, 0x22, 0x11,
441                       0x01, 0x02, 0x00, 0x5e, 0xef, 0x10, 0xaa, 0xbb, 0xcd};
442     testVector.SetIphcHeader(iphc, sizeof(iphc));
443 
444     // Set payload and error.
445     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
446     testVector.SetPayloadOffset(40);
447     testVector.SetError(kErrorNone);
448 
449     // Perform compression and decompression tests.
450     Test(testVector, true, true);
451 }
452 
TestSource64bitDestination64bitShortAddresses(void)453 static void TestSource64bitDestination64bitShortAddresses(void)
454 {
455     TestIphcVector testVector("IPv6 addresses 64-bit using short MAC addresses");
456 
457     // Setup MAC addresses.
458     testVector.SetMacSource(sTestMacSourceDefaultShort);
459     testVector.SetMacDestination(sTestMacDestinationDefaultShort);
460 
461     // Setup IPv6 header.
462     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1101",
463                            "fe80::200:5eef:10aa:bbcd");
464 
465     // Set LOWPAN_IPHC header.
466     uint8_t iphc[] = {0x7a, 0x11, 0x3a, 0x02, 0x00, 0x5e, 0xef, 0x10, 0x22, 0x11,
467                       0x01, 0x02, 0x00, 0x5e, 0xef, 0x10, 0xaa, 0xbb, 0xcd};
468     testVector.SetIphcHeader(iphc, sizeof(iphc));
469 
470     // Set payload and error.
471     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
472     testVector.SetPayloadOffset(40);
473     testVector.SetError(kErrorNone);
474 
475     // Perform compression and decompression tests.
476     Test(testVector, true, true);
477 }
478 
TestSource16bitDestination16bitAddresses(void)479 static void TestSource16bitDestination16bitAddresses(void)
480 {
481     TestIphcVector testVector("IPv6 addresses 16-bit using short MAC addresses");
482 
483     // Setup MAC addresses.
484     testVector.SetMacSource(sTestMacSourceDefaultShort);
485     testVector.SetMacDestination(sTestMacDestinationDefaultShort);
486 
487     // Setup IPv6 header.
488     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::ff:fe00:0001",
489                            "fe80::ff:fe00:c004");
490 
491     // Set LOWPAN_IPHC header.
492     uint8_t iphc[] = {0x7a, 0x22, 0x3a, 0x00, 0x01, 0xc0, 0x04};
493     testVector.SetIphcHeader(iphc, sizeof(iphc));
494 
495     // Set payload and error.
496     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
497     testVector.SetPayloadOffset(40);
498     testVector.SetError(kErrorNone);
499 
500     // Perform compression and decompression tests.
501     Test(testVector, true, true);
502 }
503 
TestSourceCompressedDestination16bitAddresses(void)504 static void TestSourceCompressedDestination16bitAddresses(void)
505 {
506     TestIphcVector testVector("Fully compressible IPv6 source and destination 16-bit using long MAC addresses");
507 
508     // Setup MAC addresses.
509     testVector.SetMacSource(sTestMacSourceDefaultLong);
510     testVector.SetMacDestination(sTestMacDestinationDefaultLong);
511 
512     // Setup IPv6 header.
513     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1100",
514                            "fe80::ff:fe00:beaf");
515 
516     // Set LOWPAN_IPHC header.
517     uint8_t iphc[] = {0x7a, 0x32, 0x3a, 0xbe, 0xaf};
518     testVector.SetIphcHeader(iphc, sizeof(iphc));
519 
520     // Set payload and error.
521     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
522     testVector.SetPayloadOffset(40);
523     testVector.SetError(kErrorNone);
524 
525     // Perform compression and decompression tests.
526     Test(testVector, true, true);
527 }
528 
TestSourceCompressedDestination128bitAddresses(void)529 static void TestSourceCompressedDestination128bitAddresses(void)
530 {
531     TestIphcVector testVector("Fully compressible IPv6 source and destination inline using long MAC addresses");
532 
533     // Setup MAC addresses.
534     testVector.SetMacSource(sTestMacSourceDefaultLong);
535     testVector.SetMacDestination(sTestMacDestinationDefaultLong);
536 
537     // Setup IPv6 header.
538     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1100",
539                            "2001:2:0:4::");
540 
541     // Set LOWPAN_IPHC header.
542     uint8_t iphc[] = {0x7a, 0x30, 0x3a, 0x20, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,
543                       0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
544     testVector.SetIphcHeader(iphc, sizeof(iphc));
545 
546     // Set payload and error.
547     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
548     testVector.SetPayloadOffset(40);
549     testVector.SetError(kErrorNone);
550 
551     // Perform compression and decompression tests.
552     Test(testVector, true, true);
553 }
554 
TestMulticast128bitAddress(void)555 static void TestMulticast128bitAddress(void)
556 {
557     TestIphcVector testVector("Multicast address inline");
558 
559     // Setup MAC addresses.
560     testVector.SetMacSource(sTestMacSourceDefaultLong);
561     testVector.SetMacDestination(sTestMacDestinationBroadcast);
562 
563     // Setup IPv6 header.
564     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1100",
565                            "ff05::100:0030:0001");
566 
567     // Set LOWPAN_IPHC header.
568     uint8_t iphc[] = {0x7a, 0x38, 0x3a, 0xff, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
569                       0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x30, 0x00, 0x01};
570     testVector.SetIphcHeader(iphc, sizeof(iphc));
571 
572     // Set payload and error.
573     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
574     testVector.SetPayloadOffset(40);
575     testVector.SetError(kErrorNone);
576 
577     // Perform compression and decompression tests.
578     Test(testVector, true, true);
579 }
580 
TestMulticast48bitAddress(void)581 static void TestMulticast48bitAddress(void)
582 {
583     TestIphcVector testVector("Multicast address 48-bit");
584 
585     // Setup MAC addresses.
586     testVector.SetMacSource(sTestMacSourceDefaultLong);
587     testVector.SetMacDestination(sTestMacDestinationBroadcast);
588 
589     // Setup IPv6 header.
590     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1100",
591                            "ff05::1:0030:0001");
592 
593     // Set LOWPAN_IPHC header.
594     uint8_t iphc[] = {0x7a, 0x39, 0x3a, 0x05, 0x01, 0x00, 0x30, 0x00, 0x01};
595     testVector.SetIphcHeader(iphc, sizeof(iphc));
596 
597     // Set payload and error.
598     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
599     testVector.SetPayloadOffset(40);
600     testVector.SetError(kErrorNone);
601 
602     // Perform compression and decompression tests.
603     Test(testVector, true, true);
604 }
605 
TestMulticast32bitAddress(void)606 static void TestMulticast32bitAddress(void)
607 {
608     TestIphcVector testVector("Multicast address 32-bit");
609 
610     // Setup MAC addresses.
611     testVector.SetMacSource(sTestMacSourceDefaultShort);
612     testVector.SetMacDestination(sTestMacDestinationBroadcast);
613 
614     // Setup IPv6 header.
615     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1100",
616                            "ff03::fc");
617 
618     // Set LOWPAN_IPHC header.
619     uint8_t iphc[] = {0x7a, 0x1a, 0x3a, 0x02, 0x00, 0x5e, 0xef, 0x10, 0x22, 0x11, 0x00, 0x03, 0x00, 0x00, 0xfc};
620     testVector.SetIphcHeader(iphc, sizeof(iphc));
621 
622     // Set payload and error.
623     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
624     testVector.SetPayloadOffset(40);
625     testVector.SetError(kErrorNone);
626 
627     // Perform compression and decompression tests.
628     Test(testVector, true, true);
629 }
630 
TestMulticast8bitAddress(void)631 static void TestMulticast8bitAddress(void)
632 {
633     TestIphcVector testVector("Multicast address 8-bit");
634 
635     // Setup MAC addresses.
636     testVector.SetMacSource(sTestMacSourceDefaultLong);
637     testVector.SetMacDestination(sTestMacDestinationBroadcast);
638 
639     // Setup IPv6 header.
640     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1100",
641                            "ff02::2");
642 
643     // Set LOWPAN_IPHC header.
644     uint8_t iphc[] = {0x7a, 0x3b, 0x3a, 0x02};
645     testVector.SetIphcHeader(iphc, sizeof(iphc));
646 
647     // Set payload and error.
648     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
649     testVector.SetPayloadOffset(40);
650     testVector.SetError(kErrorNone);
651 
652     // Perform compression and decompression tests.
653     Test(testVector, true, true);
654 }
655 
TestStatefulSource64bitDestination64bitContext0(void)656 static void TestStatefulSource64bitDestination64bitContext0(void)
657 {
658     TestIphcVector testVector("Stateful compression source and destination addresses 64-bit, context 0");
659 
660     // Setup MAC addresses.
661     testVector.SetMacSource(sTestMacSourceDefaultShort);
662     testVector.SetMacDestination(sTestMacDestinationDefaultShort);
663 
664     // Setup IPv6 header.
665     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64,
666                            "fd00:cafe:face:1234:abcd:ef01:2345:6789", "fd00:cafe:face:1234:c31d:a702:0d41:beef");
667 
668     // Set LOWPAN_IPHC header.
669     uint8_t iphc[] = {0x7a, 0x55, 0x3a, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67,
670                       0x89, 0xc3, 0x1d, 0xa7, 0x02, 0x0d, 0x41, 0xbe, 0xef};
671     testVector.SetIphcHeader(iphc, sizeof(iphc));
672 
673     // Set payload and error.
674     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
675     testVector.SetPayloadOffset(40);
676     testVector.SetError(kErrorNone);
677 
678     // Perform compression and decompression tests.
679     Test(testVector, true, true);
680 }
681 
TestStatefulSource64bitDestination64bitContext0IfContextInLine(void)682 static void TestStatefulSource64bitDestination64bitContext0IfContextInLine(void)
683 {
684     TestIphcVector testVector("Stateful compression source and destination addresses 64-bit, context 0 inline");
685 
686     // Setup MAC addresses.
687     testVector.SetMacSource(sTestMacSourceDefaultShort);
688     testVector.SetMacDestination(sTestMacDestinationDefaultShort);
689 
690     // Setup IPv6 header.
691     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64,
692                            "fd00:cafe:face:1234:abcd:ef01:2345:6789", "fd00:cafe:face:1234:c31d:a702:0d41:beef");
693 
694     // Set LOWPAN_IPHC header.
695     uint8_t iphc[] = {0x7a, 0xd5, 0x00, 0x3a, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45,
696                       0x67, 0x89, 0xc3, 0x1d, 0xa7, 0x02, 0x0d, 0x41, 0xbe, 0xef};
697     testVector.SetIphcHeader(iphc, sizeof(iphc));
698 
699     // Set payload and error.
700     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
701     testVector.SetPayloadOffset(40);
702     testVector.SetError(kErrorNone);
703 
704     // Perform decompression test only.
705     Test(testVector, false, true);
706 }
707 
TestStatefulSource16bitDestination16bitContext0(void)708 static void TestStatefulSource16bitDestination16bitContext0(void)
709 {
710     TestIphcVector testVector("Stateful compression source and destination addresses 16-bit, context 0");
711 
712     // Setup MAC addresses.
713     testVector.SetMacSource(sTestMacSourceDefaultShort);
714     testVector.SetMacDestination(sTestMacDestinationDefaultShort);
715 
716     // Setup IPv6 header.
717     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64,
718                            "fd00:cafe:face:1234::ff:fe00:fffc", "fd00:cafe:face:1234::ff:fe00:fffe");
719 
720     // Set LOWPAN_IPHC header.
721     uint8_t iphc[] = {0x7a, 0x66, 0x3a, 0xff, 0xfc, 0xff, 0xfe};
722     testVector.SetIphcHeader(iphc, sizeof(iphc));
723 
724     // Set payload and error.
725     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
726     testVector.SetPayloadOffset(40);
727     testVector.SetError(kErrorNone);
728 
729     // Perform compression and decompression tests.
730     Test(testVector, true, true);
731 }
732 
TestStatefulCompressableLongAddressesContext0(void)733 static void TestStatefulCompressableLongAddressesContext0(void)
734 {
735     TestIphcVector testVector("Stateful compression compressible long addresses, context 0");
736 
737     // Setup MAC addresses.
738     testVector.SetMacSource(sTestMacSourceDefaultLong);
739     testVector.SetMacDestination(sTestMacDestinationDefaultLong);
740 
741     // Setup IPv6 header.
742     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64,
743                            "fd00:cafe:face:1234:0200:5eef:1022:1100", "fd00:cafe:face:1234:0200:5eef:10aa:bbcc");
744 
745     // Set LOWPAN_IPHC header.
746     uint8_t iphc[] = {0x7a, 0x77, 0x3a};
747     testVector.SetIphcHeader(iphc, sizeof(iphc));
748 
749     // Set payload and error.
750     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
751     testVector.SetPayloadOffset(40);
752     testVector.SetError(kErrorNone);
753 
754     // Perform compression and decompression tests.
755     Test(testVector, true, true);
756 }
757 
TestStatefulCompressableShortAddressesContext0(void)758 static void TestStatefulCompressableShortAddressesContext0(void)
759 {
760     TestIphcVector testVector("Stateful compression compressible short addresses, context 0");
761 
762     // Setup MAC addresses.
763     testVector.SetMacSource(sTestMacSourceDefaultShort);
764     testVector.SetMacDestination(sTestMacDestinationDefaultShort);
765 
766     // Setup IPv6 header.
767     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64,
768                            "fd00:cafe:face:1234::ff:fe00:0000", "fd00:cafe:face:1234::ff:fe00:c003");
769 
770     // Set LOWPAN_IPHC header.
771     uint8_t iphc[] = {0x7a, 0x77, 0x3a};
772     testVector.SetIphcHeader(iphc, sizeof(iphc));
773 
774     // Set payload and error.
775     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
776     testVector.SetPayloadOffset(40);
777     testVector.SetError(kErrorNone);
778 
779     // Perform compression and decompression tests.
780     Test(testVector, true, true);
781 }
782 
TestStatefulCompressableLongShortAddressesContext0(void)783 static void TestStatefulCompressableLongShortAddressesContext0(void)
784 {
785     TestIphcVector testVector("Stateful compression compressible long and short addresses, context 0");
786 
787     // Setup MAC addresses.
788     testVector.SetMacSource(sTestMacSourceDefaultLong);
789     testVector.SetMacDestination(sTestMacDestinationDefaultShort);
790 
791     // Setup IPv6 header.
792     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64,
793                            "fd00:cafe:face:1234:0200:5eef:1022:1100", "fd00:cafe:face:1234::ff:fe00:c003");
794 
795     // Set LOWPAN_IPHC header.
796     uint8_t iphc[] = {0x7a, 0x77, 0x3a};
797     testVector.SetIphcHeader(iphc, sizeof(iphc));
798 
799     // Set payload and error.
800     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
801     testVector.SetPayloadOffset(40);
802     testVector.SetError(kErrorNone);
803 
804     // Perform compression and decompression tests.
805     Test(testVector, true, true);
806 }
807 
TestStatefulSource64bitDestination128bitContext1(void)808 static void TestStatefulSource64bitDestination128bitContext1(void)
809 {
810     TestIphcVector testVector("Stateful compression source addresses 64-bit and destination inline, context 1");
811 
812     // Setup MAC addresses.
813     testVector.SetMacSource(sTestMacSourceDefaultShort);
814     testVector.SetMacDestination(sTestMacDestinationDefaultShort);
815 
816     // Setup IPv6 header.
817     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64,
818                            "2001:2:0:1:abcd:ef01:2345:6789", "2001:2:0:3:c31d:a702:0d41:beef");
819 
820     // Set LOWPAN_IPHC header.
821     uint8_t iphc[] = {0x7a, 0xd0, 0x10, 0x3a, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0x20, 0x01,
822                       0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0xc3, 0x1d, 0xa7, 0x02, 0x0d, 0x41, 0xbe, 0xef};
823     testVector.SetIphcHeader(iphc, sizeof(iphc));
824 
825     // Set payload and error.
826     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
827     testVector.SetPayloadOffset(40);
828     testVector.SetError(kErrorNone);
829 
830     // Perform compression and decompression tests.
831     Test(testVector, true, true);
832 }
833 
TestStatefulSource64bitDestination64bitContext1(void)834 static void TestStatefulSource64bitDestination64bitContext1(void)
835 {
836     TestIphcVector testVector("Stateful compression source and destination addresses 64-bit, context 1");
837 
838     // Setup MAC addresses.
839     testVector.SetMacSource(sTestMacSourceDefaultShort);
840     testVector.SetMacDestination(sTestMacDestinationDefaultShort);
841 
842     // Setup IPv6 header.
843     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64,
844                            "2001:2:0:1:abcd:ef01:2345:6789", "2001:2:0:1:c31d:a702:0d41:beef");
845 
846     // Set LOWPAN_IPHC header.
847     uint8_t iphc[] = {0x7a, 0xd5, 0x11, 0x3a, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45,
848                       0x67, 0x89, 0xc3, 0x1d, 0xa7, 0x02, 0x0d, 0x41, 0xbe, 0xef};
849     testVector.SetIphcHeader(iphc, sizeof(iphc));
850 
851     // Set payload and error.
852     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
853     testVector.SetPayloadOffset(40);
854     testVector.SetError(kErrorNone);
855 
856     // Perform compression and decompression tests.
857     Test(testVector, true, true);
858 }
859 
TestStatefulSourceDestinationInlineContext2CIDFalse(void)860 static void TestStatefulSourceDestinationInlineContext2CIDFalse(void)
861 {
862     TestIphcVector testVector("Stateful compression source and destination addresses inline, context 2 (C=FALSE)");
863 
864     // Setup MAC addresses.
865     testVector.SetMacSource(sTestMacSourceDefaultShort);
866     testVector.SetMacDestination(sTestMacDestinationDefaultShort);
867 
868     // Setup IPv6 header.
869     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64,
870                            "2001:2:0:2:abcd:ef01:2345:6789", "2001:2:0:2:c31d:a702:0d41:beef");
871 
872     // Set LOWPAN_IPHC header.
873     uint8_t iphc[] = {0x7a, 0x00, 0x3a, 0x20, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0xab,
874                       0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0x20, 0x01, 0x00, 0x02, 0x00,
875                       0x00, 0x00, 0x02, 0xc3, 0x1d, 0xa7, 0x02, 0x0d, 0x41, 0xbe, 0xef};
876     testVector.SetIphcHeader(iphc, sizeof(iphc));
877 
878     // Set payload and error.
879     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
880     testVector.SetPayloadOffset(40);
881     testVector.SetError(kErrorNone);
882 
883     // Perform compression test only.
884     Test(testVector, true, false);
885 }
886 
TestStatefulMulticastDestination48bitContext0(void)887 static void TestStatefulMulticastDestination48bitContext0(void)
888 {
889     TestIphcVector testVector("Stateful compression multicast address, context 0");
890 
891     // Setup MAC addresses.
892     testVector.SetMacSource(sTestMacSourceDefaultLong);
893     testVector.SetMacDestination(sTestMacDestinationDefaultShort);
894 
895     // Setup IPv6 header.
896     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64,
897                            "fd00:cafe:face:1234:0200:5eef:1022:1100", "ff33:0040:fd00:cafe:face:1234:0000:0001");
898 
899     // Set LOWPAN_IPHC header.
900     uint8_t iphc[] = {0x7a, 0x7c, 0x3a, 0x33, 0x00, 0x00, 0x00, 0x00, 0x01};
901     testVector.SetIphcHeader(iphc, sizeof(iphc));
902 
903     // Set payload and error.
904     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
905     testVector.SetPayloadOffset(40);
906     testVector.SetError(kErrorNone);
907 
908     // Perform decompression tests.
909     Test(testVector, true, true);
910 }
911 
TestTrafficClassFlowLabel3Bytes(void)912 static void TestTrafficClassFlowLabel3Bytes(void)
913 {
914     TestIphcVector testVector("Traffic Class and Flow Label 3 bytes");
915 
916     // Setup MAC addresses.
917     testVector.SetMacSource(sTestMacSourceDefaultLong);
918     testVector.SetMacDestination(sTestMacDestinationDefaultLong);
919 
920     // Setup IPv6 header.
921     testVector.SetIpHeader(0x6011ac59, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1100",
922                            "fe80::200:5eef:10aa:bbcc");
923 
924     // Set LOWPAN_IPHC header.
925     uint8_t iphc[] = {0x6a, 0x33, 0x41, 0xac, 0x59, 0x3a};
926     testVector.SetIphcHeader(iphc, sizeof(iphc));
927 
928     // Set payload and error.
929     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
930     testVector.SetPayloadOffset(40);
931     testVector.SetError(kErrorNone);
932 
933     // Perform compression and decompression tests.
934     Test(testVector, true, true);
935 }
936 
TestTrafficClassFlowLabel1Byte(void)937 static void TestTrafficClassFlowLabel1Byte(void)
938 {
939     TestIphcVector testVector("Traffic Class and Flow Label 1 byte");
940 
941     // Setup MAC addresses.
942     testVector.SetMacSource(sTestMacSourceDefaultLong);
943     testVector.SetMacDestination(sTestMacDestinationDefaultLong);
944 
945     // Setup IPv6 header.
946     testVector.SetIpHeader(0x60d00000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1100",
947                            "fe80::200:5eef:10aa:bbcc");
948 
949     // Set LOWPAN_IPHC header.
950     uint8_t iphc[] = {0x72, 0x33, 0x43, 0x3a};
951     testVector.SetIphcHeader(iphc, sizeof(iphc));
952 
953     // Set payload and error.
954     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
955     testVector.SetPayloadOffset(40);
956     testVector.SetError(kErrorNone);
957 
958     // Perform compression and decompression tests.
959     Test(testVector, true, true);
960 }
961 
TestTrafficClassFlowLabel1ByteEcnOnly(void)962 static void TestTrafficClassFlowLabel1ByteEcnOnly(void)
963 {
964     TestIphcVector testVector("Traffic Class and Flow Label 1 byte with ecn only");
965 
966     // Setup MAC addresses.
967     testVector.SetMacSource(sTestMacSourceDefaultLong);
968     testVector.SetMacDestination(sTestMacDestinationDefaultLong);
969 
970     // Setup IPv6 header.
971     testVector.SetIpHeader(0x60100000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1100",
972                            "fe80::200:5eef:10aa:bbcc");
973 
974     // Set LOWPAN_IPHC header.
975     uint8_t iphc[] = {0x72, 0x33, 0x40, 0x3a};
976     testVector.SetIphcHeader(iphc, sizeof(iphc));
977 
978     // Set payload and error.
979     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
980     testVector.SetPayloadOffset(40);
981     testVector.SetError(kErrorNone);
982 
983     // Perform compression and decompression tests.
984     Test(testVector, true, true);
985 }
986 
TestTrafficClassFlowLabelInline(void)987 static void TestTrafficClassFlowLabelInline(void)
988 {
989     TestIphcVector testVector("Traffic Class and Flow Label inline");
990 
991     // Setup MAC addresses.
992     testVector.SetMacSource(sTestMacSourceDefaultLong);
993     testVector.SetMacDestination(sTestMacDestinationDefaultLong);
994 
995     // Setup IPv6 header.
996     testVector.SetIpHeader(0x6ea12345, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1100",
997                            "fe80::200:5eef:10aa:bbcc");
998 
999     // Set LOWPAN_IPHC header.
1000     uint8_t iphc[] = {0x62, 0x33, 0xBA, 0x01, 0x23, 0x45, 0x3a};
1001     testVector.SetIphcHeader(iphc, sizeof(iphc));
1002 
1003     // Set payload and error.
1004     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
1005     testVector.SetPayloadOffset(40);
1006     testVector.SetError(kErrorNone);
1007 
1008     // Perform compression and decompression tests.
1009     Test(testVector, true, true);
1010 }
1011 
TestHopLimit1(void)1012 static void TestHopLimit1(void)
1013 {
1014     TestIphcVector testVector("Hop Limit 1");
1015 
1016     // Setup MAC addresses.
1017     testVector.SetMacSource(sTestMacSourceDefaultShort);
1018     testVector.SetMacDestination(sTestMacDestinationDefaultShort);
1019 
1020     // Setup IPv6 header.
1021     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 1, "fe80::ff:fe00:0000",
1022                            "fe80::ff:fe00:c003");
1023 
1024     // Set LOWPAN_IPHC header.
1025     uint8_t iphc[] = {0x79, 0x33, 0x3a};
1026     testVector.SetIphcHeader(iphc, sizeof(iphc));
1027 
1028     // Set payload and error.
1029     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
1030     testVector.SetPayloadOffset(40);
1031     testVector.SetError(kErrorNone);
1032 
1033     // Perform compression and decompression tests.
1034     Test(testVector, true, true);
1035 }
1036 
TestHopLimit255(void)1037 static void TestHopLimit255(void)
1038 {
1039     TestIphcVector testVector("Hop Limit 255");
1040 
1041     // Setup MAC addresses.
1042     testVector.SetMacSource(sTestMacSourceDefaultShort);
1043     testVector.SetMacDestination(sTestMacDestinationDefaultShort);
1044 
1045     // Setup IPv6 header.
1046     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 255, "fe80::ff:fe00:0000",
1047                            "fe80::ff:fe00:c003");
1048 
1049     // Set LOWPAN_IPHC header.
1050     uint8_t iphc[] = {0x7B, 0x33, 0x3a};
1051     testVector.SetIphcHeader(iphc, sizeof(iphc));
1052 
1053     // Set payload and error.
1054     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
1055     testVector.SetPayloadOffset(40);
1056     testVector.SetError(kErrorNone);
1057 
1058     // Perform compression and decompression tests.
1059     Test(testVector, true, true);
1060 }
1061 
TestHopLimitInline(void)1062 static void TestHopLimitInline(void)
1063 {
1064     TestIphcVector testVector("Hop Limit Inline");
1065 
1066     // Setup MAC addresses.
1067     testVector.SetMacSource(sTestMacSourceDefaultShort);
1068     testVector.SetMacDestination(sTestMacDestinationDefaultShort);
1069 
1070     // Setup IPv6 header.
1071     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 63, "fe80::ff:fe00:0000",
1072                            "fe80::ff:fe00:c003");
1073 
1074     // Set LOWPAN_IPHC header.
1075     uint8_t iphc[] = {0x78, 0x33, 0x3a, 0x3f};
1076     testVector.SetIphcHeader(iphc, sizeof(iphc));
1077 
1078     // Set payload and error.
1079     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
1080     testVector.SetPayloadOffset(40);
1081     testVector.SetError(kErrorNone);
1082 
1083     // Perform compression and decompression tests.
1084     Test(testVector, true, true);
1085 }
1086 
TestUdpSourceDestinationInline(void)1087 static void TestUdpSourceDestinationInline(void)
1088 {
1089     TestIphcVector testVector("UDP source and destination inline");
1090 
1091     // Setup MAC addresses.
1092     testVector.SetMacSource(sTestMacSourceDefaultLong);
1093     testVector.SetMacDestination(sTestMacDestinationDefaultLong);
1094 
1095     // Setup IPv6 header.
1096     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoUdp, 64, "fe80::200:5eef:1022:1100",
1097                            "fe80::200:5eef:10aa:bbcc");
1098 
1099     // Setup UDP header.
1100     testVector.SetUDPHeader(5683, 5684, sizeof(sTestPayloadDefault) + 8, 0xbeef);
1101 
1102     // Set LOWPAN_IPHC header.
1103     uint8_t iphc[] = {0x7e, 0x33, 0xf0, 0x16, 0x33, 0x16, 0x34, 0xbe, 0xef};
1104     testVector.SetIphcHeader(iphc, sizeof(iphc));
1105 
1106     // Set payload and error.
1107     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
1108     testVector.SetPayloadOffset(48);
1109     testVector.SetError(kErrorNone);
1110 
1111     // Perform compression and decompression tests.
1112     Test(testVector, true, true);
1113 }
1114 
TestUdpSourceInlineDestination8bit(void)1115 static void TestUdpSourceInlineDestination8bit(void)
1116 {
1117     TestIphcVector testVector("UDP source inline destination 8-bit");
1118 
1119     // Setup MAC addresses.
1120     testVector.SetMacSource(sTestMacSourceDefaultLong);
1121     testVector.SetMacDestination(sTestMacDestinationDefaultLong);
1122 
1123     // Setup IPv6 header.
1124     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoUdp, 64, "fe80::200:5eef:1022:1100",
1125                            "fe80::200:5eef:10aa:bbcc");
1126 
1127     // Setup UDP header.
1128     testVector.SetUDPHeader(5683, 61441, sizeof(sTestPayloadDefault) + 8, 0xbeef);
1129 
1130     // Set LOWPAN_IPHC header.
1131     uint8_t iphc[] = {0x7e, 0x33, 0xf1, 0x16, 0x33, 0x01, 0xbe, 0xef};
1132     testVector.SetIphcHeader(iphc, sizeof(iphc));
1133 
1134     // Set payload and error.
1135     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
1136     testVector.SetPayloadOffset(48);
1137     testVector.SetError(kErrorNone);
1138 
1139     // Perform compression and decompression tests.
1140     Test(testVector, true, true);
1141 }
1142 
TestUdpSource8bitDestinationInline(void)1143 static void TestUdpSource8bitDestinationInline(void)
1144 {
1145     TestIphcVector testVector("UDP source 8-bit destination 8-bit");
1146 
1147     // Setup MAC addresses.
1148     testVector.SetMacSource(sTestMacSourceDefaultLong);
1149     testVector.SetMacDestination(sTestMacDestinationDefaultLong);
1150 
1151     // Setup IPv6 header.
1152     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoUdp, 64, "fe80::200:5eef:1022:1100",
1153                            "fe80::200:5eef:10aa:bbcc");
1154 
1155     // Setup UDP header.
1156     testVector.SetUDPHeader(61695, 5683, sizeof(sTestPayloadDefault) + 8, 0xbeef);
1157 
1158     // Set LOWPAN_IPHC header.
1159     uint8_t iphc[] = {0x7e, 0x33, 0xf2, 0xff, 0x16, 0x33, 0xbe, 0xef};
1160     testVector.SetIphcHeader(iphc, sizeof(iphc));
1161 
1162     // Set payload and error.
1163     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
1164     testVector.SetPayloadOffset(48);
1165     testVector.SetError(kErrorNone);
1166 
1167     // Perform compression and decompression tests.
1168     Test(testVector, true, true);
1169 }
1170 
TestUdpFullyCompressed(void)1171 static void TestUdpFullyCompressed(void)
1172 {
1173     TestIphcVector testVector("UDP fully compressed");
1174 
1175     // Setup MAC addresses.
1176     testVector.SetMacSource(sTestMacSourceDefaultLong);
1177     testVector.SetMacDestination(sTestMacDestinationDefaultLong);
1178 
1179     // Setup IPv6 header.
1180     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoUdp, 64, "fe80::200:5eef:1022:1100",
1181                            "fe80::200:5eef:10aa:bbcc");
1182 
1183     // Setup UDP header.
1184     testVector.SetUDPHeader(61616, 61631, sizeof(sTestPayloadDefault) + 8, 0xface);
1185 
1186     // Set LOWPAN_IPHC header.
1187     uint8_t iphc[] = {0x7e, 0x33, 0xf3, 0x0f, 0xfa, 0xce};
1188     testVector.SetIphcHeader(iphc, sizeof(iphc));
1189 
1190     // Set payload and error.
1191     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
1192     testVector.SetPayloadOffset(48);
1193     testVector.SetError(kErrorNone);
1194 
1195     // Perform compression and decompression tests.
1196     Test(testVector, true, true);
1197 }
1198 
TestUdpFullyCompressedMulticast(void)1199 static void TestUdpFullyCompressedMulticast(void)
1200 {
1201     TestIphcVector testVector("UDP fully compressed with IP multicast");
1202 
1203     // Setup MAC addresses.
1204     testVector.SetMacSource(sTestMacSourceDefaultLong);
1205     testVector.SetMacDestination(sTestMacDestinationDefaultLong);
1206 
1207     // Setup IPv6 header.
1208     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoUdp, 64, "fe80::200:5eef:1022:1100",
1209                            "ff02::1");
1210 
1211     // Setup UDP header.
1212     testVector.SetUDPHeader(61616, 61631, sizeof(sTestPayloadDefault) + 8, 0xface);
1213 
1214     // Set LOWPAN_IPHC header.
1215     uint8_t iphc[] = {0x7e, 0x3b, 0x01, 0xf3, 0x0f, 0xfa, 0xce};
1216     testVector.SetIphcHeader(iphc, sizeof(iphc));
1217 
1218     // Set payload and error.
1219     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
1220     testVector.SetPayloadOffset(48);
1221     testVector.SetError(kErrorNone);
1222 
1223     // Perform compression and decompression tests.
1224     Test(testVector, true, true);
1225 }
1226 
TestUdpWithoutNhc(void)1227 static void TestUdpWithoutNhc(void)
1228 {
1229     TestIphcVector testVector("UDP without LOWPAN_NHC compression");
1230 
1231     // Setup MAC addresses.
1232     testVector.SetMacSource(sTestMacSourceDefaultShort);
1233     testVector.SetMacDestination(sTestMacDestinationDefaultShort);
1234 
1235     // Setup IPv6 header.
1236     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoUdp, 64, "fe80::ff:fe00:0000",
1237                            "fe80::ff:fe00:c003");
1238 
1239     // Set LOWPAN_IPHC header.
1240     uint8_t iphc[] = {0x7a, 0x33, 0x11};
1241     testVector.SetIphcHeader(iphc, sizeof(iphc));
1242 
1243     // Set payload and error.
1244     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
1245     testVector.SetPayloadOffset(40);
1246     testVector.SetError(kErrorNone);
1247 
1248     // Perform only decompression test.
1249     Test(testVector, false, true);
1250 }
1251 
TestExtensionHeaderHopByHopNoPadding(void)1252 static void TestExtensionHeaderHopByHopNoPadding(void)
1253 {
1254     TestIphcVector testVector("Extension Header - Hop-by-Hop with no padding");
1255 
1256     // Setup MAC addresses.
1257     testVector.SetMacSource(sTestMacSourceDefaultShort);
1258     testVector.SetMacDestination(sTestMacDestinationBroadcast);
1259 
1260     // Setup IPv6 header.
1261     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoHopOpts, 64,
1262                            "fd00:cafe:face:1234::ff:fe00:0000", "ff03::1");
1263 
1264     // Setup extension header.
1265     uint8_t extHeader[] = {0x3a, 0x00, 0x6d, 0x04, 0x60, 0x11, 0x00, 0x0c};
1266     testVector.SetExtHeader(extHeader, sizeof(extHeader));
1267 
1268     // Set LOWPAN_IPHC header.
1269     uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x3a, 0x06, 0x6d, 0x04, 0x60, 0x11, 0x00, 0x0c};
1270     testVector.SetIphcHeader(iphc, sizeof(iphc));
1271 
1272     // Set payload and error.
1273     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
1274     testVector.SetPayloadOffset(48);
1275     testVector.SetError(kErrorNone);
1276 
1277     // Perform compression and decompression tests.
1278     Test(testVector, true, true);
1279 }
1280 
TestExtensionHeaderHopByHopPad1(void)1281 static void TestExtensionHeaderHopByHopPad1(void)
1282 {
1283     TestIphcVector testVector("Extension Header - Hop-by-Hop with Pad1");
1284 
1285     // Setup MAC addresses.
1286     testVector.SetMacSource(sTestMacSourceDefaultShort);
1287     testVector.SetMacDestination(sTestMacDestinationBroadcast);
1288 
1289     // Setup IPv6 header.
1290     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoHopOpts, 64,
1291                            "fd00:cafe:face:1234::ff:fe00:0000", "ff03::1");
1292 
1293     // Setup extension header.
1294     uint8_t extHeader[] = {0x3a, 0x00, 0x6d, 0x03, 0x60, 0x11, 0x00, 0x00};
1295     testVector.SetExtHeader(extHeader, sizeof(extHeader));
1296 
1297     // Set LOWPAN_IPHC header.
1298     uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x3a, 0x05, 0x6d, 0x03, 0x60, 0x11, 0x00};
1299     testVector.SetIphcHeader(iphc, sizeof(iphc));
1300 
1301     // Set payload and error.
1302     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
1303     testVector.SetPayloadOffset(48);
1304     testVector.SetError(kErrorNone);
1305 
1306     // Perform compression and decompression tests.
1307     Test(testVector, true, true);
1308 }
1309 
TestExtensionHeaderHopByHopPadN2(void)1310 static void TestExtensionHeaderHopByHopPadN2(void)
1311 {
1312     TestIphcVector testVector("Extension Header - Hop-by-Hop with PadN2");
1313 
1314     // Setup MAC addresses.
1315     testVector.SetMacSource(sTestMacSourceDefaultShort);
1316     testVector.SetMacDestination(sTestMacDestinationBroadcast);
1317 
1318     // Setup IPv6 header.
1319     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoHopOpts, 64,
1320                            "fd00:cafe:face:1234::ff:fe00:0000", "ff03::1");
1321 
1322     // Setup extension header.
1323     uint8_t extHeader[] = {0x3a, 0x00, 0x6d, 0x02, 0x60, 0x11, 0x01, 0x00};
1324     testVector.SetExtHeader(extHeader, sizeof(extHeader));
1325 
1326     // Set LOWPAN_IPHC header.
1327     uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x3a, 0x04, 0x6d, 0x02, 0x60, 0x11};
1328     testVector.SetIphcHeader(iphc, sizeof(iphc));
1329 
1330     // Set payload and error.
1331     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
1332     testVector.SetPayloadOffset(48);
1333     testVector.SetError(kErrorNone);
1334 
1335     // Perform compression and decompression tests.
1336     Test(testVector, true, true);
1337 }
1338 
TestExtensionHeaderHopByHopPadN3(void)1339 static void TestExtensionHeaderHopByHopPadN3(void)
1340 {
1341     TestIphcVector testVector("Extension Header - Hop-by-Hop with PadN3");
1342 
1343     // Setup MAC addresses.
1344     testVector.SetMacSource(sTestMacSourceDefaultShort);
1345     testVector.SetMacDestination(sTestMacDestinationBroadcast);
1346 
1347     // Setup IPv6 header.
1348     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoHopOpts, 64,
1349                            "fd00:cafe:face:1234::ff:fe00:0000", "ff03::1");
1350 
1351     // Setup extension header.
1352     uint8_t extHeader[] = {0x3a, 0x00, 0x6d, 0x01, 0x60, 0x01, 0x01, 0x00};
1353     testVector.SetExtHeader(extHeader, sizeof(extHeader));
1354 
1355     // Set LOWPAN_IPHC header.
1356     uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x3a, 0x03, 0x6d, 0x01, 0x60};
1357     testVector.SetIphcHeader(iphc, sizeof(iphc));
1358 
1359     // Set payload and error.
1360     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
1361     testVector.SetPayloadOffset(48);
1362     testVector.SetError(kErrorNone);
1363 
1364     // Perform compression and decompression tests.
1365     Test(testVector, true, true);
1366 }
1367 
TestExtensionHeaderHopByHopPadN4(void)1368 static void TestExtensionHeaderHopByHopPadN4(void)
1369 {
1370     TestIphcVector testVector("Extension Header - Hop-by-Hop with PadN4");
1371 
1372     // Setup MAC addresses.
1373     testVector.SetMacSource(sTestMacSourceDefaultShort);
1374     testVector.SetMacDestination(sTestMacDestinationBroadcast);
1375 
1376     // Setup IPv6 header.
1377     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoHopOpts, 64,
1378                            "fd00:cafe:face:1234::ff:fe00:0000", "ff03::1");
1379 
1380     // Setup extension header.
1381     uint8_t extHeader[] = {0x3a, 0x00, 0x6d, 0x00, 0x01, 0x02, 0x00, 0x00};
1382     testVector.SetExtHeader(extHeader, sizeof(extHeader));
1383 
1384     // Set LOWPAN_IPHC header.
1385     uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x3a, 0x02, 0x6d, 0x00};
1386     testVector.SetIphcHeader(iphc, sizeof(iphc));
1387 
1388     // Set payload and error.
1389     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
1390     testVector.SetPayloadOffset(48);
1391     testVector.SetError(kErrorNone);
1392 
1393     // Perform compression and decompression tests.
1394     Test(testVector, true, true);
1395 }
1396 
TestExtensionHeaderHopByHopPadN5(void)1397 static void TestExtensionHeaderHopByHopPadN5(void)
1398 {
1399     TestIphcVector testVector("Extension Header - Hop-by-Hop with PadN5");
1400 
1401     // Setup MAC addresses.
1402     testVector.SetMacSource(sTestMacSourceDefaultShort);
1403     testVector.SetMacDestination(sTestMacDestinationBroadcast);
1404 
1405     // Setup IPv6 header.
1406     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 16, Ip6::kProtoHopOpts, 64,
1407                            "fd00:cafe:face:1234::ff:fe00:0000", "ff03::1");
1408 
1409     // Setup extension header.
1410     uint8_t extHeader[] = {0x3a, 0x01, 0x6d, 0x07, 0x01, 0x02, 0x01, 0x00,
1411                            0x00, 0x00, 0x33, 0x01, 0x03, 0x00, 0x00, 0x00};
1412     testVector.SetExtHeader(extHeader, sizeof(extHeader));
1413 
1414     // Set LOWPAN_IPHC header.
1415     uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x3a, 0x09,
1416                       0x6d, 0x07, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x33};
1417     testVector.SetIphcHeader(iphc, sizeof(iphc));
1418 
1419     // Set payload and error.
1420     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
1421     testVector.SetPayloadOffset(56);
1422     testVector.SetError(kErrorNone);
1423 
1424     // Perform compression and decompression tests.
1425     Test(testVector, true, true);
1426 }
1427 
TestExtensionHeaderHopByHopPadN6(void)1428 static void TestExtensionHeaderHopByHopPadN6(void)
1429 {
1430     TestIphcVector testVector("Extension Header - Hop-by-Hop with PadN6");
1431 
1432     // Setup MAC addresses.
1433     testVector.SetMacSource(sTestMacSourceDefaultShort);
1434     testVector.SetMacDestination(sTestMacDestinationBroadcast);
1435 
1436     // Setup IPv6 header.
1437     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 24, Ip6::kProtoHopOpts, 64,
1438                            "fd00:cafe:face:1234::ff:fe00:0000", "ff03::1");
1439 
1440     // Setup extension header.
1441     uint8_t extHeader[] = {0x3a, 0x02, 0x6d, 0x0e, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x33, 0x01,
1442                            0x03, 0x00, 0x00, 0x00, 0x11, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00};
1443     testVector.SetExtHeader(extHeader, sizeof(extHeader));
1444 
1445     // Set LOWPAN_IPHC header.
1446     uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x3a, 0x10, 0x6d, 0x0e, 0x01, 0x02,
1447                       0x01, 0x00, 0x00, 0x00, 0x33, 0x01, 0x03, 0x00, 0x00, 0x00, 0x11, 0x00};
1448     testVector.SetIphcHeader(iphc, sizeof(iphc));
1449 
1450     // Set payload and error.
1451     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
1452     testVector.SetPayloadOffset(64);
1453     testVector.SetError(kErrorNone);
1454 
1455     // Perform compression and decompression tests.
1456     Test(testVector, true, true);
1457 }
1458 
TestExtensionHeaderHopByHopPadN7(void)1459 static void TestExtensionHeaderHopByHopPadN7(void)
1460 {
1461     TestIphcVector testVector("Extension Header - Hop-by-Hop with PadN7");
1462 
1463     // Setup MAC addresses.
1464     testVector.SetMacSource(sTestMacSourceDefaultShort);
1465     testVector.SetMacDestination(sTestMacDestinationBroadcast);
1466 
1467     // Setup IPv6 header.
1468     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 24, Ip6::kProtoHopOpts, 64,
1469                            "fd00:cafe:face:1234::ff:fe00:0000", "ff03::1");
1470 
1471     // Setup extension header.
1472     uint8_t extHeader[] = {0x3a, 0x02, 0x6d, 0x0d, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x33, 0x01,
1473                            0x03, 0x00, 0x00, 0x00, 0x11, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00};
1474     testVector.SetExtHeader(extHeader, sizeof(extHeader));
1475 
1476     // Set LOWPAN_IPHC header.
1477     uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x3a, 0x0f, 0x6d, 0x0d, 0x01,
1478                       0x02, 0x01, 0x00, 0x00, 0x00, 0x33, 0x01, 0x03, 0x00, 0x00, 0x00, 0x11};
1479     testVector.SetIphcHeader(iphc, sizeof(iphc));
1480 
1481     // Set payload and error.
1482     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
1483     testVector.SetPayloadOffset(64);
1484     testVector.SetError(kErrorNone);
1485 
1486     // Perform compression and decompression tests.
1487     Test(testVector, true, true);
1488 }
1489 
TestExtensionHeaderHopByHopPadN2UdpFullyCompressed(void)1490 static void TestExtensionHeaderHopByHopPadN2UdpFullyCompressed(void)
1491 {
1492     TestIphcVector testVector("Extension Header - Hop-by-Hop with PadN2 and UDP");
1493 
1494     // Setup MAC addresses.
1495     testVector.SetMacSource(sTestMacSourceDefaultShort);
1496     testVector.SetMacDestination(sTestMacDestinationBroadcast);
1497 
1498     // Setup IPv6 header.
1499     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 16, Ip6::kProtoHopOpts, 64,
1500                            "fd00:cafe:face:1234::ff:fe00:0000", "ff03::1");
1501 
1502     // Setup extension header.
1503     uint8_t extHeader[] = {0x11, 0x00, 0x6d, 0x02, 0x60, 0x11, 0x01, 0x00};
1504     testVector.SetExtHeader(extHeader, sizeof(extHeader));
1505 
1506     // Setup UDP header.
1507     testVector.SetUDPHeader(61616, 61631, sizeof(sTestPayloadDefault) + 8, 0xface);
1508 
1509     // Set LOWPAN_IPHC header.
1510     uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe1, 0x04, 0x6d, 0x02, 0x60, 0x11, 0xf3, 0x0f, 0xfa, 0xce};
1511     testVector.SetIphcHeader(iphc, sizeof(iphc));
1512 
1513     // Set payload and error.
1514     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
1515     testVector.SetPayloadOffset(56);
1516     testVector.SetError(kErrorNone);
1517 
1518     // Perform compression and decompression tests.
1519     Test(testVector, true, true);
1520 }
1521 
TestIpInIpHopByHopPadN2UdpSourceDestinationInline(void)1522 static void TestIpInIpHopByHopPadN2UdpSourceDestinationInline(void)
1523 {
1524     TestIphcVector testVector("IP-in-IP with Hop-by-Hop with PadN2 and UDP");
1525 
1526     // Setup MAC addresses.
1527     testVector.SetMacSource(sTestMacSourceDefaultShort);
1528     testVector.SetMacDestination(sTestMacDestinationBroadcast);
1529 
1530     // Setup IPv6 header.
1531     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 56, Ip6::kProtoHopOpts, 64,
1532                            "fd00:cafe:face:1234::ff:fe00:0000", "ff03::fc");
1533 
1534     // Setup extension header.
1535     uint8_t extHeader[] = {0x29, 0x00, 0x6d, 0x02, 0x00, 0x11, 0x01, 0x00};
1536     testVector.SetExtHeader(extHeader, sizeof(extHeader));
1537 
1538     // Setup IPv6 tunneled header.
1539     testVector.SetIpTunneledHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoUdp, 64,
1540                                    "fd00:cafe:face:1234::ff:fe00:0000", "ff05::1");
1541 
1542     // Setup UDP header.
1543     testVector.SetUDPHeader(5683, 5684, sizeof(sTestPayloadDefault) + 8, 0xbeef);
1544 
1545     // Set LOWPAN_IPHC header.
1546     uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0xfc, 0xe1, 0x04, 0x6d, 0x02, 0x00, 0x11, 0xee,
1547                       0x7e, 0x7a, 0x05, 0x00, 0x00, 0x01, 0xf0, 0x16, 0x33, 0x16, 0x34, 0xbe, 0xef};
1548     testVector.SetIphcHeader(iphc, sizeof(iphc));
1549 
1550     // Set payload and error.
1551     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
1552     testVector.SetPayloadOffset(96);
1553     testVector.SetError(kErrorNone);
1554 
1555     // Perform compression and decompression tests.
1556     Test(testVector, true, true);
1557 }
1558 
TestIpInIpWithoutExtensionHeader(void)1559 static void TestIpInIpWithoutExtensionHeader(void)
1560 {
1561     TestIphcVector testVector("IP-in-IP without extension header");
1562 
1563     // Setup MAC addresses.
1564     testVector.SetMacSource(sTestMacSourceDefaultLong);
1565     testVector.SetMacDestination(sTestMacDestinationDefaultLong);
1566 
1567     // Setup IPv6 header.
1568     testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 40, Ip6::kProtoIp6, 64, "fe80::200:5eef:1022:1100",
1569                            "ff03::1");
1570 
1571     // Setup IPv6 tunneled header.
1572     testVector.SetIpTunneledHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 1,
1573                                    "fe80::200:5eef:1022:1100", "fe80::200:5eef:10aa:bbcc");
1574 
1575     // Set LOWPAN_IPHC header.
1576     uint8_t iphc[] = {0x7e, 0x3a, 0x03, 0x00, 0x00, 0x01, 0xee, 0x79, 0x33, 0x3a};
1577     testVector.SetIphcHeader(iphc, sizeof(iphc));
1578 
1579     // Set payload and error.
1580     testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault));
1581     testVector.SetPayloadOffset(80);
1582     testVector.SetError(kErrorNone);
1583 
1584     // Perform compression and decompression tests.
1585     Test(testVector, true, true);
1586 }
1587 
TestErrorNoIphcDispatch(void)1588 static void TestErrorNoIphcDispatch(void)
1589 {
1590     TestIphcVector testVector("Invalid dispatch");
1591 
1592     // Setup MAC addresses.
1593     testVector.SetMacSource(sTestMacSourceDefaultLong);
1594     testVector.SetMacDestination(sTestMacDestinationDefaultLong);
1595 
1596     // Set LOWPAN_IPHC header.
1597     uint8_t iphc[] = {0x40, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
1598     testVector.SetIphcHeader(iphc, sizeof(iphc));
1599 
1600     // Set payload and error.
1601     testVector.SetError(kErrorParse);
1602 
1603     // Perform decompression test.
1604     Test(testVector, false, true);
1605 }
1606 
TestErrorTruncatedIphc(void)1607 static void TestErrorTruncatedIphc(void)
1608 {
1609     TestIphcVector testVector("Truncated LOWPAN_IPHC");
1610 
1611     // Setup MAC addresses.
1612     testVector.SetMacSource(sTestMacSourceDefaultLong);
1613     testVector.SetMacDestination(sTestMacDestinationDefaultLong);
1614 
1615     // Set LOWPAN_IPHC header.
1616     uint8_t iphc[] = {0x7a, 0x00};
1617     testVector.SetIphcHeader(iphc, sizeof(iphc));
1618 
1619     // Set payload and error.
1620     testVector.SetError(kErrorParse);
1621 
1622     // Perform decompression test.
1623     Test(testVector, false, true);
1624 }
1625 
TestErrorReservedValueDestination0100(void)1626 static void TestErrorReservedValueDestination0100(void)
1627 {
1628     TestIphcVector testVector("Reserved value of M-DAC-DAM - 0100");
1629 
1630     // Setup MAC addresses.
1631     testVector.SetMacSource(sTestMacSourceDefaultLong);
1632     testVector.SetMacDestination(sTestMacDestinationDefaultLong);
1633 
1634     // Set LOWPAN_IPHC header.
1635     uint8_t iphc[] = {0x7a, 0x34, 0x3A};
1636     testVector.SetIphcHeader(iphc, sizeof(iphc));
1637 
1638     // Set payload and error.
1639     testVector.SetError(kErrorParse);
1640 
1641     // Perform decompression test.
1642     Test(testVector, false, true);
1643 }
1644 
TestErrorReservedValueDestination1101(void)1645 static void TestErrorReservedValueDestination1101(void)
1646 {
1647     TestIphcVector testVector("Reserved value of M-DAC-DAM - 1101");
1648 
1649     // Setup MAC addresses.
1650     testVector.SetMacSource(sTestMacSourceDefaultLong);
1651     testVector.SetMacDestination(sTestMacDestinationDefaultLong);
1652 
1653     // Set LOWPAN_IPHC header.
1654     uint8_t iphc[] = {0x7a, 0x3D, 0x3A};
1655     testVector.SetIphcHeader(iphc, sizeof(iphc));
1656 
1657     // Set payload and error.
1658     testVector.SetError(kErrorParse);
1659 
1660     // Perform decompression test.
1661     Test(testVector, false, true);
1662 }
1663 
TestErrorReservedValueDestination1110(void)1664 static void TestErrorReservedValueDestination1110(void)
1665 {
1666     TestIphcVector testVector("Reserved value of M-DAC-DAM - 1110");
1667 
1668     // Setup MAC addresses.
1669     testVector.SetMacSource(sTestMacSourceDefaultLong);
1670     testVector.SetMacDestination(sTestMacDestinationDefaultLong);
1671 
1672     // Set LOWPAN_IPHC header.
1673     uint8_t iphc[] = {0x7a, 0x3E, 0x3A};
1674     testVector.SetIphcHeader(iphc, sizeof(iphc));
1675 
1676     // Set payload and error.
1677     testVector.SetError(kErrorParse);
1678 
1679     // Perform decompression test.
1680     Test(testVector, false, true);
1681 }
1682 
TestErrorReservedValueDestination1111(void)1683 static void TestErrorReservedValueDestination1111(void)
1684 {
1685     TestIphcVector testVector("Reserved value of M-DAC-DAM - 1111");
1686 
1687     // Setup MAC addresses.
1688     testVector.SetMacSource(sTestMacSourceDefaultLong);
1689     testVector.SetMacDestination(sTestMacDestinationDefaultLong);
1690 
1691     // Set LOWPAN_IPHC header.
1692     uint8_t iphc[] = {0x7a, 0x3F, 0x3A};
1693     testVector.SetIphcHeader(iphc, sizeof(iphc));
1694 
1695     // Set payload and error.
1696     testVector.SetError(kErrorParse);
1697 
1698     // Perform decompression test.
1699     Test(testVector, false, true);
1700 }
1701 
TestErrorUnknownNhc(void)1702 static void TestErrorUnknownNhc(void)
1703 {
1704     TestIphcVector testVector("Unknown value of LOWPAN_NHC ID");
1705 
1706     // Setup MAC addresses.
1707     testVector.SetMacSource(sTestMacSourceDefaultLong);
1708     testVector.SetMacDestination(sTestMacDestinationDefaultLong);
1709 
1710     // Set LOWPAN_IPHC header.
1711     uint8_t iphc[] = {0x7e, 0x33, 0x00};
1712     testVector.SetIphcHeader(iphc, sizeof(iphc));
1713 
1714     // Set payload and error.
1715     testVector.SetError(kErrorParse);
1716 
1717     // Perform decompression test.
1718     Test(testVector, false, true);
1719 }
1720 
TestErrorReservedNhc5(void)1721 static void TestErrorReservedNhc5(void)
1722 {
1723     TestIphcVector testVector("Reserved value of LOWPAN_NHC EID - 0x05");
1724 
1725     // Setup MAC addresses.
1726     testVector.SetMacSource(sTestMacSourceDefaultLong);
1727     testVector.SetMacDestination(sTestMacDestinationDefaultLong);
1728 
1729     // Set LOWPAN_IPHC header.
1730     uint8_t iphc[] = {0x7e, 0x33, 0xea};
1731     testVector.SetIphcHeader(iphc, sizeof(iphc));
1732 
1733     // Set payload and error.
1734     testVector.SetError(kErrorParse);
1735 
1736     // Perform decompression test.
1737     Test(testVector, false, true);
1738 }
1739 
TestErrorReservedNhc6(void)1740 static void TestErrorReservedNhc6(void)
1741 {
1742     TestIphcVector testVector("Reserved value of LOWPAN_NHC EID - 0x06");
1743 
1744     // Setup MAC addresses.
1745     testVector.SetMacSource(sTestMacSourceDefaultLong);
1746     testVector.SetMacDestination(sTestMacDestinationDefaultLong);
1747 
1748     // Set LOWPAN_IPHC header.
1749     uint8_t iphc[] = {0x7e, 0x33, 0xec};
1750     testVector.SetIphcHeader(iphc, sizeof(iphc));
1751 
1752     // Set payload and error.
1753     testVector.SetError(kErrorParse);
1754 
1755     // Perform decompression test.
1756     Test(testVector, false, true);
1757 }
1758 
1759 /***************************************************************************************************
1760  * @section Main test.
1761  **************************************************************************************************/
1762 
TestLowpanIphc(void)1763 void TestLowpanIphc(void)
1764 {
1765     sInstance = testInitInstance();
1766 
1767     VerifyOrQuit(sInstance != nullptr, "nullptr instance");
1768 
1769     sIp6    = &sInstance->Get<Ip6::Ip6>();
1770     sLowpan = &sInstance->Get<Lowpan::Lowpan>();
1771 
1772     Init();
1773 
1774     // Stateless unicast addresses compression / decompression tests.
1775     TestFullyCompressableLongAddresses();
1776     TestFullyCompressableShortAddresses();
1777     TestFullyCompressableShortLongAddresses();
1778     TestFullyCompressableLongShortAddresses();
1779     TestSourceUnspecifiedAddress();
1780     TestSource128bitDestination128bitAddresses();
1781     TestSource64bitDestination64bitLongAddresses();
1782     TestSource64bitDestination64bitShortAddresses();
1783     TestSource16bitDestination16bitAddresses();
1784     TestSourceCompressedDestination16bitAddresses();
1785     TestSourceCompressedDestination128bitAddresses();
1786 
1787     // Stateless multicast addresses compression / decompression tests.
1788     TestMulticast128bitAddress();
1789     TestMulticast48bitAddress();
1790     TestMulticast32bitAddress();
1791     TestMulticast8bitAddress();
1792 
1793     // Stateful unicast addresses compression / decompression tests.
1794     TestStatefulSource64bitDestination64bitContext0();
1795     TestStatefulSource64bitDestination64bitContext0IfContextInLine();
1796     TestStatefulSource16bitDestination16bitContext0();
1797     TestStatefulCompressableLongAddressesContext0();
1798     TestStatefulCompressableShortAddressesContext0();
1799     TestStatefulCompressableLongShortAddressesContext0();
1800     TestStatefulSource64bitDestination128bitContext1();
1801     TestStatefulSource64bitDestination64bitContext1();
1802     TestStatefulSourceDestinationInlineContext2CIDFalse();
1803 
1804     // Stateful multicast addresses compression / decompression tests.
1805     TestStatefulMulticastDestination48bitContext0();
1806 
1807     // Traffic Class and Flow Label compression / decompression tests.
1808     TestTrafficClassFlowLabel3Bytes();
1809     TestTrafficClassFlowLabel1Byte();
1810     TestTrafficClassFlowLabel1ByteEcnOnly();
1811     TestTrafficClassFlowLabelInline();
1812 
1813     // Hop Limit compression / decompression tests.
1814     TestHopLimit1();
1815     TestHopLimit255();
1816     TestHopLimitInline();
1817 
1818     // UDP compression / decompression tests.
1819     TestUdpSourceDestinationInline();
1820     TestUdpSourceInlineDestination8bit();
1821     TestUdpSource8bitDestinationInline();
1822     TestUdpFullyCompressed();
1823     TestUdpFullyCompressedMulticast();
1824     TestUdpWithoutNhc();
1825 
1826     // Extension Headers compression / decompression tests.
1827     TestExtensionHeaderHopByHopNoPadding();
1828     TestExtensionHeaderHopByHopPad1();
1829     TestExtensionHeaderHopByHopPadN2();
1830     TestExtensionHeaderHopByHopPadN3();
1831     TestExtensionHeaderHopByHopPadN4();
1832     TestExtensionHeaderHopByHopPadN5();
1833     TestExtensionHeaderHopByHopPadN6();
1834     TestExtensionHeaderHopByHopPadN7();
1835     TestExtensionHeaderHopByHopPadN2UdpFullyCompressed();
1836 
1837     // IP-in-IP compression / decompression tests.
1838     TestIpInIpHopByHopPadN2UdpSourceDestinationInline();
1839     TestIpInIpWithoutExtensionHeader();
1840 
1841     // Invalid frame to be decompressed.
1842     TestErrorNoIphcDispatch();
1843     TestErrorTruncatedIphc();
1844     TestErrorReservedValueDestination0100();
1845     TestErrorReservedValueDestination1101();
1846     TestErrorReservedValueDestination1110();
1847     TestErrorReservedValueDestination1111();
1848     TestErrorUnknownNhc();
1849     TestErrorReservedNhc5();
1850     TestErrorReservedNhc6();
1851 
1852     testFreeInstance(sInstance);
1853 }
1854 
TestLowpanMeshHeader(void)1855 void TestLowpanMeshHeader(void)
1856 {
1857     enum
1858     {
1859         kMaxFrameSize = 127,
1860         kSourceAddr   = 0x100,
1861         kDestAddr     = 0x200,
1862     };
1863 
1864     const uint8_t kMeshHeader1[] = {0xb1, 0x01, 0x00, 0x02, 0x00};       // src:0x100, dest:0x200, hop:0x1
1865     const uint8_t kMeshHeader2[] = {0xbf, 0x20, 0x01, 0x00, 0x02, 0x00}; // src:0x100, dest:0x200, hop:0x20
1866     const uint8_t kMeshHeader3[] = {0xbf, 0x01, 0x01, 0x00, 0x02, 0x00}; // src:0x100, dest:0x200, hop:0x1 (deepHops)
1867 
1868     uint8_t            frame[kMaxFrameSize];
1869     uint16_t           length;
1870     FrameData          frameData;
1871     FrameBuilder       frameBuilder;
1872     Lowpan::MeshHeader meshHeader;
1873 
1874     meshHeader.Init(kSourceAddr, kDestAddr, 1);
1875     VerifyOrQuit(meshHeader.GetSource() == kSourceAddr, "failed after Init()");
1876     VerifyOrQuit(meshHeader.GetDestination() == kDestAddr, "failed after Init()");
1877     VerifyOrQuit(meshHeader.GetHopsLeft() == 1, "failed after Init()");
1878 
1879     frameBuilder.Init(frame, sizeof(frame));
1880     SuccessOrQuit(meshHeader.AppendTo(frameBuilder));
1881     length = frameBuilder.GetLength();
1882     VerifyOrQuit(length == meshHeader.GetHeaderLength());
1883     VerifyOrQuit(length == sizeof(kMeshHeader1), "MeshHeader::AppendTo() returned length is incorrect");
1884     VerifyOrQuit(memcmp(frame, kMeshHeader1, length) == 0, "MeshHeader::AppendTo() failed");
1885 
1886     memset(&meshHeader, 0, sizeof(meshHeader));
1887     frameData.Init(frame, length);
1888     VerifyOrQuit(Lowpan::MeshHeader::IsMeshHeader(frameData));
1889     SuccessOrQuit(meshHeader.ParseFrom(frameData));
1890     VerifyOrQuit(frameData.GetLength() == 0, "ParseFrom() did not skip over parsed content");
1891     VerifyOrQuit(frameData.GetBytes() - frame == length, "ParseFrom() did not skip over parsed content");
1892     VerifyOrQuit(meshHeader.GetSource() == kSourceAddr, "failed after ParseFrom()");
1893     VerifyOrQuit(meshHeader.GetDestination() == kDestAddr, "failed after ParseFrom()");
1894     VerifyOrQuit(meshHeader.GetHopsLeft() == 1, "failed after ParseFrom()");
1895 
1896     frameData.Init(frame, length - 1);
1897     VerifyOrQuit(meshHeader.ParseFrom(frameData) == kErrorParse,
1898                  "MeshHeader::ParseFrom() did not fail with incorrect length");
1899 
1900     //- - - - - - - - - - - - - - - - - - - - - - - - - -
1901 
1902     meshHeader.Init(kSourceAddr, kDestAddr, 0x20);
1903     VerifyOrQuit(meshHeader.GetSource() == kSourceAddr, "failed after Init()");
1904     VerifyOrQuit(meshHeader.GetDestination() == kDestAddr, "failed after Init()");
1905     VerifyOrQuit(meshHeader.GetHopsLeft() == 0x20, "failed after Init()");
1906 
1907     frameBuilder.Init(frame, sizeof(frame));
1908     SuccessOrQuit(meshHeader.AppendTo(frameBuilder));
1909     length = frameBuilder.GetLength();
1910     VerifyOrQuit(length == sizeof(kMeshHeader2), "MeshHeader::AppendTo() returned length is incorrect");
1911     VerifyOrQuit(length == meshHeader.GetHeaderLength());
1912     VerifyOrQuit(memcmp(frame, kMeshHeader2, length) == 0, "MeshHeader::AppendTo() failed");
1913 
1914     memset(&meshHeader, 0, sizeof(meshHeader));
1915     frameData.Init(frame, length);
1916     VerifyOrQuit(Lowpan::MeshHeader::IsMeshHeader(frameData));
1917     SuccessOrQuit(meshHeader.ParseFrom(frameData));
1918     VerifyOrQuit(frameData.GetLength() == 0, "ParseFrom() did not skip over parsed content");
1919     VerifyOrQuit(frameData.GetBytes() - frame == length, "ParseFrom() did not skip over parsed content");
1920     VerifyOrQuit(meshHeader.GetSource() == kSourceAddr, "failed after ParseFrom()");
1921     VerifyOrQuit(meshHeader.GetDestination() == kDestAddr, "failed after ParseFrom()");
1922     VerifyOrQuit(meshHeader.GetHopsLeft() == 0x20, "failed after ParseFrom()");
1923 
1924     frameData.Init(frame, length - 1);
1925     VerifyOrQuit(meshHeader.ParseFrom(frameData) == kErrorParse,
1926                  "MeshHeader::ParseFrom() did not fail with incorrect length");
1927 
1928     //- - - - - - - - - - - - - - - - - - - - - - - - - -
1929 
1930     length = sizeof(kMeshHeader3);
1931     frameData.Init(kMeshHeader3, sizeof(kMeshHeader3));
1932     SuccessOrQuit(meshHeader.ParseFrom(frameData));
1933     VerifyOrQuit(frameData.GetLength() == 0, "ParseFrom() did not skip over parsed content");
1934     VerifyOrQuit(frameData.GetBytes() - kMeshHeader3 == length, "ParseFrom() did not skip over parsed content");
1935     VerifyOrQuit(meshHeader.GetSource() == kSourceAddr, "failed after ParseFrom()");
1936     VerifyOrQuit(meshHeader.GetDestination() == kDestAddr, "failed after ParseFrom()");
1937     VerifyOrQuit(meshHeader.GetHopsLeft() == 1, "failed after ParseFrom()");
1938 
1939     frameBuilder.Init(frame, sizeof(frame));
1940     SuccessOrQuit(meshHeader.AppendTo(frameBuilder));
1941     VerifyOrQuit(frameBuilder.GetLength() == sizeof(kMeshHeader1));
1942 
1943     frameData.Init(kMeshHeader3, sizeof(kMeshHeader3) - 1);
1944     VerifyOrQuit(meshHeader.ParseFrom(frameData) == kErrorParse,
1945                  "MeshHeader::ParseFrom() did not fail with incorrect length");
1946 }
1947 
TestLowpanFragmentHeader(void)1948 void TestLowpanFragmentHeader(void)
1949 {
1950     static constexpr uint16_t kMaxFrameSize = 127;
1951     static constexpr uint16_t kSize         = 0x7ef;
1952     static constexpr uint16_t kTag          = 0x1234;
1953     static constexpr uint16_t kOffset       = (100 * 8);
1954 
1955     const uint8_t kFragHeader1[] = {0xc7, 0xef, 0x12, 0x34};       // size:0x7ef, tag:0x1234, offset:0 (first frag)
1956     const uint8_t kFragHeader2[] = {0xe7, 0xef, 0x12, 0x34, 0x64}; // size:0x7ef, tag:0x1234, offset:100 (next frag)
1957     const uint8_t kFragHeader3[] = {0xe7, 0xef, 0x12, 0x34, 0x00}; // size:0x7ef, tag:0x1234, offset:0 (next frag)
1958 
1959     const uint8_t kInvalidFragHeader1[] = {0xe8, 0xef, 0x12, 0x34, 0x64};
1960     const uint8_t kInvalidFragHeader2[] = {0xd0, 0xef, 0x12, 0x34, 0x64};
1961     const uint8_t kInvalidFragHeader3[] = {0x90, 0xef, 0x12, 0x34, 0x64};
1962 
1963     uint8_t                           frame[kMaxFrameSize];
1964     uint16_t                          length;
1965     FrameData                         frameData;
1966     FrameBuilder                      frameBuilder;
1967     Lowpan::FragmentHeader            fragHeader;
1968     Lowpan::FragmentHeader::FirstFrag firstFragHeader;
1969     Lowpan::FragmentHeader::NextFrag  nextFragHeader;
1970 
1971     frameBuilder.Init(frame, sizeof(frame));
1972 
1973     firstFragHeader.Init(kSize, kTag);
1974     SuccessOrQuit(frameBuilder.Append(firstFragHeader));
1975 
1976     length = frameBuilder.GetLength();
1977     VerifyOrQuit(length == sizeof(Lowpan::FragmentHeader::FirstFrag));
1978     VerifyOrQuit(memcmp(frame, kFragHeader1, length) == 0);
1979 
1980     memset(&fragHeader, 0, sizeof(fragHeader));
1981 
1982     frameData.Init(frame, length);
1983     VerifyOrQuit(Lowpan::FragmentHeader::IsFragmentHeader(frameData));
1984     SuccessOrQuit(fragHeader.ParseFrom(frameData));
1985     VerifyOrQuit(frameData.GetLength() == 0, "ParseFrom() did not skip over parsed content");
1986     VerifyOrQuit(frameData.GetBytes() - frame == length, "ParseFrom() did not skip over parsed content");
1987     VerifyOrQuit(fragHeader.GetDatagramSize() == kSize, "failed after ParseFrom()");
1988     VerifyOrQuit(fragHeader.GetDatagramTag() == kTag, "failed after ParseFrom()");
1989     VerifyOrQuit(fragHeader.GetDatagramOffset() == 0, "failed after ParseFrom()");
1990 
1991     frameData.Init(frame, length - 1);
1992     VerifyOrQuit(fragHeader.ParseFrom(frameData) == kErrorParse,
1993                  "FragmentHeader::ParseFrom() did not fail with incorrect length");
1994     VerifyOrQuit(frameData.GetLength() == length - 1);
1995     VerifyOrQuit(frameData.GetBytes() == frame);
1996 
1997     //- - - - - - - - - - - - - - - - - - - - - - - - - -
1998 
1999     frameBuilder.Init(frame, sizeof(frame));
2000     nextFragHeader.Init(kSize, kTag, kOffset);
2001     SuccessOrQuit(frameBuilder.Append(nextFragHeader));
2002     length = frameBuilder.GetLength();
2003     VerifyOrQuit(length == sizeof(kFragHeader2));
2004     VerifyOrQuit(memcmp(frame, kFragHeader2, length) == 0);
2005 
2006     // Check the truncation of offset (to be multiple of 8).
2007     frameBuilder.Init(frame, sizeof(frame));
2008     nextFragHeader.Init(kSize, kTag, kOffset + 1);
2009     SuccessOrQuit(frameBuilder.Append(nextFragHeader));
2010     length = frameBuilder.GetLength();
2011     VerifyOrQuit(length == sizeof(kFragHeader2));
2012     VerifyOrQuit(memcmp(frame, kFragHeader2, length) == 0);
2013 
2014     frameBuilder.Init(frame, sizeof(frame));
2015     nextFragHeader.Init(kSize, kTag, kOffset + 7);
2016     SuccessOrQuit(frameBuilder.Append(nextFragHeader));
2017     length = frameBuilder.GetLength();
2018     VerifyOrQuit(length == sizeof(kFragHeader2));
2019     VerifyOrQuit(memcmp(frame, kFragHeader2, length) == 0);
2020 
2021     memset(&fragHeader, 0, sizeof(fragHeader));
2022     frameData.Init(frame, length);
2023     VerifyOrQuit(Lowpan::FragmentHeader::IsFragmentHeader(frameData));
2024     SuccessOrQuit(fragHeader.ParseFrom(frameData));
2025     VerifyOrQuit(frameData.GetLength() == 0, "ParseFrom() did not skip over parsed content");
2026     VerifyOrQuit(frameData.GetBytes() - frame == length, "ParseFrom() did not skip over parsed content");
2027     VerifyOrQuit(fragHeader.GetDatagramSize() == kSize, "failed after ParseFrom()");
2028     VerifyOrQuit(fragHeader.GetDatagramTag() == kTag, "failed after ParseFrom()");
2029     VerifyOrQuit(fragHeader.GetDatagramOffset() == kOffset, "failed after ParseFrom()");
2030 
2031     frameData.Init(frame, length - 1);
2032     VerifyOrQuit(fragHeader.ParseFrom(frameData) == kErrorParse,
2033                  "FragmentHeader::ParseFrom() did not fail with incorrect length");
2034     VerifyOrQuit(frameData.GetLength() == length - 1);
2035     VerifyOrQuit(frameData.GetBytes() == frame);
2036 
2037     //- - - - - - - - - - - - - - - - - - - - - - - - - -
2038 
2039     length = sizeof(kFragHeader3);
2040     memcpy(frame, kFragHeader3, length);
2041     frameData.Init(frame, length);
2042     SuccessOrQuit(fragHeader.ParseFrom(frameData));
2043     VerifyOrQuit(frameData.GetLength() == 0, "ParseFrom() did not skip over parsed content");
2044     VerifyOrQuit(frameData.GetBytes() - frame == length, "ParseFrom() did not skip over parsed content");
2045     VerifyOrQuit(fragHeader.GetDatagramSize() == kSize, "failed after ParseFrom()");
2046     VerifyOrQuit(fragHeader.GetDatagramTag() == kTag, "failed after ParseFrom()");
2047     VerifyOrQuit(fragHeader.GetDatagramOffset() == 0, "failed after ParseFrom()");
2048 
2049     frameData.Init(frame, length - 1);
2050     VerifyOrQuit(fragHeader.ParseFrom(frameData) == kErrorParse,
2051                  "FragmentHeader::ParseFrom() did not fail with incorrect length");
2052     VerifyOrQuit(frameData.GetLength() == length - 1);
2053     VerifyOrQuit(frameData.GetBytes() == frame);
2054 
2055     //- - - - - - - - - - - - - - - - - - - - - - - - - -
2056 
2057     length = sizeof(kInvalidFragHeader1);
2058     memcpy(frame, kInvalidFragHeader1, length);
2059     frameData.Init(frame, length);
2060     VerifyOrQuit(!Lowpan::FragmentHeader::IsFragmentHeader(frameData),
2061                  "IsFragmentHeader() did not detect invalid header");
2062     VerifyOrQuit(fragHeader.ParseFrom(frameData) != kErrorNone,
2063                  "FragmentHeader::ParseFrom() did not fail with invalid header");
2064     VerifyOrQuit(frameData.GetLength() == length);
2065     VerifyOrQuit(frameData.GetBytes() == frame);
2066 
2067     length = sizeof(kInvalidFragHeader2);
2068     memcpy(frame, kInvalidFragHeader2, length);
2069     frameData.Init(frame, length);
2070     VerifyOrQuit(!Lowpan::FragmentHeader::IsFragmentHeader(frameData),
2071                  "IsFragmentHeader() did not detect invalid header");
2072     VerifyOrQuit(fragHeader.ParseFrom(frameData) != kErrorNone,
2073                  "FragmentHeader::ParseFrom() did not fail with invalid header");
2074     VerifyOrQuit(frameData.GetLength() == length);
2075     VerifyOrQuit(frameData.GetBytes() == frame);
2076 
2077     length = sizeof(kInvalidFragHeader3);
2078     memcpy(frame, kInvalidFragHeader3, length);
2079     frameData.Init(frame, length);
2080     VerifyOrQuit(!Lowpan::FragmentHeader::IsFragmentHeader(frameData),
2081                  "IsFragmentHeader() did not detect invalid header");
2082     VerifyOrQuit(fragHeader.ParseFrom(frameData) != kErrorNone,
2083                  "FragmentHeader::ParseFrom() did not fail with invalid header");
2084     VerifyOrQuit(frameData.GetLength() == length);
2085     VerifyOrQuit(frameData.GetBytes() == frame);
2086 }
2087 
2088 } // namespace ot
2089 
main(void)2090 int main(void)
2091 {
2092     ot::TestLowpanIphc();
2093     ot::TestLowpanMeshHeader();
2094     ot::TestLowpanFragmentHeader();
2095 
2096     printf("All tests passed\n");
2097     return 0;
2098 }
2099