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