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