/* * Copyright (c) 2016, The OpenThread Authors. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holder nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include "test_lowpan.hpp" #include "test_platform.h" #include "test_util.hpp" namespace ot { Instance *sInstance; Ip6::Ip6 *sIp6; Lowpan::Lowpan *sLowpan; void TestIphcVector::GetCompressedStream(uint8_t *aIphc, uint16_t &aIphcLength) { memcpy(aIphc, mIphcHeader.mData, mIphcHeader.mLength); memcpy(aIphc + mIphcHeader.mLength, mPayload.mData, mPayload.mLength); aIphcLength = mIphcHeader.mLength + mPayload.mLength; } void TestIphcVector::GetUncompressedStream(uint8_t *aIp6, uint16_t &aIp6Length) { aIp6Length = 0; memcpy(aIp6, reinterpret_cast(&mIpHeader), sizeof(mIpHeader)); aIp6Length += sizeof(mIpHeader); if (mExtHeader.mLength) { memcpy(aIp6 + aIp6Length, mExtHeader.mData, mExtHeader.mLength); aIp6Length += mExtHeader.mLength; } if (mIpTunneledHeader.GetPayloadLength()) { memcpy(aIp6 + aIp6Length, reinterpret_cast(&mIpTunneledHeader), sizeof(mIpTunneledHeader)); aIp6Length += sizeof(mIpTunneledHeader); } if (mUdpHeader.GetLength()) { memcpy(aIp6 + aIp6Length, reinterpret_cast(&mUdpHeader), sizeof(mUdpHeader)); aIp6Length += sizeof(mUdpHeader); } memcpy(aIp6 + aIp6Length, mPayload.mData, mPayload.mLength); aIp6Length += mPayload.mLength; } void TestIphcVector::GetUncompressedStream(Message &aMessage) { SuccessOrQuit(aMessage.Append(mIpHeader)); if (mExtHeader.mLength) { SuccessOrQuit(aMessage.AppendBytes(mExtHeader.mData, mExtHeader.mLength)); } if (mIpTunneledHeader.GetPayloadLength()) { SuccessOrQuit(aMessage.Append(mIpTunneledHeader)); } if (mUdpHeader.GetLength()) { SuccessOrQuit(aMessage.Append(mUdpHeader)); } SuccessOrQuit(aMessage.AppendBytes(mPayload.mData, mPayload.mLength)); } /** * Initializes Thread Interface. * */ static void Init(void) { otMeshLocalPrefix meshLocalPrefix = {{0xfd, 0x00, 0xca, 0xfe, 0xfa, 0xce, 0x12, 0x34}}; OffsetRange offsetRange; sInstance->Get().SetMeshLocalPrefix(static_cast(meshLocalPrefix)); // Emulate global prefixes with contextes. uint8_t mockNetworkData[] = { 0x0c, // MLE Network Data Type 0x20, // MLE Network Data Length // Prefix 2001:2:0:1::/64 0x03, 0x0e, // Prefix TLV 0x00, 0x40, 0x20, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x07, 0x02, // 6LoWPAN Context ID TLV 0x11, 0x40, // Context ID = 1, C = TRUE // Prefix 2001:2:0:2::/64 0x03, 0x0e, // Prefix TLV 0x00, 0x40, 0x20, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x07, 0x02, // 6LoWPAN Context ID TLV 0x02, 0x40 // Context ID = 2, C = FALSE }; Message *message = sInstance->Get().Allocate(Message::kTypeIp6); VerifyOrQuit(message != nullptr, "Ip6::NewMessage failed"); SuccessOrQuit(message->AppendBytes(mockNetworkData, sizeof(mockNetworkData))); offsetRange.Init(2, 0x20); IgnoreError( sInstance->Get().SetNetworkData(0, 0, NetworkData::kStableSubset, *message, offsetRange)); } /** * Performs compression or/and decompression based on the given test vector. * * @note Performing decompression and compression on the same LOWPAN_IPHC frame may give different result. * This situation may occur when sender does not use the best possible compression, * e.g. doesn't use LOWPAN_NHC for UDP - which is still valid. * * @param aVector Test vector that has to be tested. * @param aCompress Set to TRUE, if compression should be tested. * @param aDecompress Set to TRUE, if decomrpession should be tested. */ static void Test(TestIphcVector &aVector, bool aCompress, bool aDecompress) { Message *message = nullptr; uint8_t result[512]; uint8_t iphc[512]; uint8_t ip6[512]; uint16_t iphcLength; uint16_t ip6Length; FrameData frameData; Error error; aVector.GetCompressedStream(iphc, iphcLength); aVector.GetUncompressedStream(ip6, ip6Length); printf("\n=== Test name: %s ===\n\n", aVector.mTestName); printf("Expected error -------------- %s\n", aVector.mError ? "yes" : "no"); printf("UDP present ----------------- %s\n", aVector.mUdpHeader.GetLength() ? "yes" : "no"); printf("Extension Headers present --- %s\n", aVector.mExtHeader.mLength ? "yes" : "no"); printf("IP-in-IP present ------------ %s\n", aVector.mIpTunneledHeader.GetPayloadLength() ? "yes" : "no"); printf("LOWPAN_IPHC length ---------- %d\n", aVector.mIphcHeader.mLength); printf("IPv6 uncompressed offset ---- %d\n\n", aVector.mPayloadOffset); DumpBuffer("Expected IPv6 uncompressed packet", ip6, ip6Length); DumpBuffer("Expected LOWPAN_IPHC compressed frame", iphc, iphcLength); if (aCompress) { FrameBuilder frameBuilder; Message *compressedMsg; Ip6::Ecn ecn; frameBuilder.Init(result, 127); VerifyOrQuit((message = sInstance->Get().Allocate(Message::kTypeIp6)) != nullptr); aVector.GetUncompressedStream(*message); VerifyOrQuit(sLowpan->Compress(*message, aVector.mMacAddrs, frameBuilder) == aVector.mError); if (aVector.mError == kErrorNone) { uint16_t compressBytes = frameBuilder.GetLength(); // Append payload to the LOWPAN_IPHC. message->ReadBytes(message->GetOffset(), result + compressBytes, message->GetLength() - message->GetOffset()); DumpBuffer("Resulted LOWPAN_IPHC compressed frame", result, compressBytes + message->GetLength() - message->GetOffset()); VerifyOrQuit(compressBytes == aVector.mIphcHeader.mLength, "Lowpan::Compress failed"); VerifyOrQuit(message->GetOffset() == aVector.mPayloadOffset, "Lowpan::Compress failed"); VerifyOrQuit(memcmp(iphc, result, iphcLength) == 0, "Lowpan::Compress failed"); // Validate `DecompressEcn()` and `MarkCompressedEcn()` VerifyOrQuit((compressedMsg = sInstance->Get().Allocate(Message::kTypeIp6)) != nullptr); SuccessOrQuit(compressedMsg->AppendBytes(result, compressBytes)); ecn = sLowpan->DecompressEcn(*compressedMsg, /* aOffset */ 0); VerifyOrQuit(ecn == aVector.GetIpHeader().GetEcn()); printf("Decompressed ECN is %d\n", ecn); if (ecn != Ip6::kEcnNotCapable) { sLowpan->MarkCompressedEcn(*compressedMsg, /*a aOffset */ 0); ecn = sLowpan->DecompressEcn(*compressedMsg, /* aOffset */ 0); VerifyOrQuit(ecn == Ip6::kEcnMarked); printf("ECN is updated to %d\n", ecn); } compressedMsg->Free(); } message->Free(); message = nullptr; } if (aDecompress) { VerifyOrQuit((message = sInstance->Get().Allocate(Message::kTypeIp6)) != nullptr); frameData.Init(iphc, iphcLength); error = sLowpan->Decompress(*message, aVector.mMacAddrs, frameData, 0); message->ReadBytes(0, result, message->GetLength()); if (aVector.mError == kErrorNone) { SuccessOrQuit(error, "Lowpan::Decompress failed"); // Append payload to the IPv6 Packet. memcpy(result + message->GetLength(), frameData.GetBytes(), frameData.GetLength()); DumpBuffer("Resulted IPv6 uncompressed packet", result, message->GetLength() + frameData.GetLength()); VerifyOrQuit((frameData.GetBytes() - iphc) == aVector.mIphcHeader.mLength, "Lowpan::Decompress failed"); VerifyOrQuit(message->GetOffset() == aVector.mPayloadOffset, "Lowpan::Decompress failed"); VerifyOrQuit(message->GetOffset() == message->GetLength(), "Lowpan::Decompress failed"); VerifyOrQuit(memcmp(ip6, result, ip6Length) == 0, "Lowpan::Decompress failed"); } else { VerifyOrQuit(error == kErrorParse, "Lowpan::Decompress failed"); } message->Free(); message = nullptr; } printf("PASS\n\n"); } /*************************************************************************************************** * @section Test constants. **************************************************************************************************/ static const uint8_t sTestMacSourceDefaultLong[] = {0x00, 0x00, 0x5e, 0xef, 0x10, 0x22, 0x11, 0x00}; static const uint8_t sTestMacDestinationDefaultLong[] = {0x00, 0x00, 0x5e, 0xef, 0x10, 0xaa, 0xbb, 0xcc}; static uint16_t sTestMacSourceDefaultShort = 0x0000; static uint16_t sTestMacDestinationDefaultShort = 0xc003; static uint16_t sTestMacDestinationBroadcast = 0xffff; static const uint8_t sTestPayloadDefault[] = {0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06}; /*************************************************************************************************** * @section Test cases. **************************************************************************************************/ static void TestFullyCompressableLongAddresses(void) { TestIphcVector testVector("Fully compressible IPv6 addresses using long MAC addresses"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultLong); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1100", "fe80::200:5eef:10aa:bbcc"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x33, 0x3a}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestFullyCompressableShortAddresses(void) { TestIphcVector testVector("Fully compressible IPv6 addresses using short MAC addresses"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultShort); testVector.SetMacDestination(sTestMacDestinationDefaultShort); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::ff:fe00:0000", "fe80::ff:fe00:c003"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x33, 0x3a}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestFullyCompressableShortLongAddresses(void) { TestIphcVector testVector("Fully compressible IPv6 addresses using short and long MAC addresses"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultShort); testVector.SetMacDestination(sTestMacDestinationDefaultLong); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::ff:fe00:0000", "fe80::200:5eef:10aa:bbcc"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x33, 0x3a}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestFullyCompressableLongShortAddresses(void) { TestIphcVector testVector("Fully compressible IPv6 addresses using long and short MAC addresses"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultShort); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1100", "fe80::ff:fe00:c003"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x33, 0x3a}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestSourceUnspecifiedAddress(void) { TestIphcVector testVector("Unspecified source IPv6 address"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultShort); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "::", "fe80::ff:fe00:c003"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x43, 0x3a}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestSource128bitDestination128bitAddresses(void) { TestIphcVector testVector("IPv6 addresses inline"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultShort); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "2001:2:0:3:aaaa:bbbb:cccc:dddd", "2001:2:0:4::"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x00, 0x3a, 0x20, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0xaa, 0xaa, 0xbb, 0xbb, 0xcc, 0xcc, 0xdd, 0xdd, 0x20, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestSource64bitDestination64bitLongAddresses(void) { TestIphcVector testVector("IPv6 addresses 64-bit using long MAC addresses"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultLong); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1101", "fe80::200:5eef:10aa:bbcd"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x11, 0x3a, 0x02, 0x00, 0x5e, 0xef, 0x10, 0x22, 0x11, 0x01, 0x02, 0x00, 0x5e, 0xef, 0x10, 0xaa, 0xbb, 0xcd}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestSource64bitDestination64bitShortAddresses(void) { TestIphcVector testVector("IPv6 addresses 64-bit using short MAC addresses"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultShort); testVector.SetMacDestination(sTestMacDestinationDefaultShort); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1101", "fe80::200:5eef:10aa:bbcd"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x11, 0x3a, 0x02, 0x00, 0x5e, 0xef, 0x10, 0x22, 0x11, 0x01, 0x02, 0x00, 0x5e, 0xef, 0x10, 0xaa, 0xbb, 0xcd}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestSource16bitDestination16bitAddresses(void) { TestIphcVector testVector("IPv6 addresses 16-bit using short MAC addresses"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultShort); testVector.SetMacDestination(sTestMacDestinationDefaultShort); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::ff:fe00:0001", "fe80::ff:fe00:c004"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x22, 0x3a, 0x00, 0x01, 0xc0, 0x04}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestSourceCompressedDestination16bitAddresses(void) { TestIphcVector testVector("Fully compressible IPv6 source and destination 16-bit using long MAC addresses"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultLong); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1100", "fe80::ff:fe00:beaf"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x32, 0x3a, 0xbe, 0xaf}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestSourceCompressedDestination128bitAddresses(void) { TestIphcVector testVector("Fully compressible IPv6 source and destination inline using long MAC addresses"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultLong); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1100", "2001:2:0:4::"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x30, 0x3a, 0x20, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestMulticast128bitAddress(void) { TestIphcVector testVector("Multicast address inline"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationBroadcast); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1100", "ff05::100:0030:0001"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x38, 0x3a, 0xff, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x30, 0x00, 0x01}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestMulticast48bitAddress(void) { TestIphcVector testVector("Multicast address 48-bit"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationBroadcast); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1100", "ff05::1:0030:0001"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x39, 0x3a, 0x05, 0x01, 0x00, 0x30, 0x00, 0x01}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestMulticast32bitAddress(void) { TestIphcVector testVector("Multicast address 32-bit"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultShort); testVector.SetMacDestination(sTestMacDestinationBroadcast); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1100", "ff03::fc"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x1a, 0x3a, 0x02, 0x00, 0x5e, 0xef, 0x10, 0x22, 0x11, 0x00, 0x03, 0x00, 0x00, 0xfc}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestMulticast8bitAddress(void) { TestIphcVector testVector("Multicast address 8-bit"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationBroadcast); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1100", "ff02::2"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x3b, 0x3a, 0x02}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestStatefulSource64bitDestination64bitContext0(void) { TestIphcVector testVector("Stateful compression source and destination addresses 64-bit, context 0"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultShort); testVector.SetMacDestination(sTestMacDestinationDefaultShort); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fd00:cafe:face:1234:abcd:ef01:2345:6789", "fd00:cafe:face:1234:c31d:a702:0d41:beef"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x55, 0x3a, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xc3, 0x1d, 0xa7, 0x02, 0x0d, 0x41, 0xbe, 0xef}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestStatefulSource64bitDestination64bitContext0IfContextInLine(void) { TestIphcVector testVector("Stateful compression source and destination addresses 64-bit, context 0 inline"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultShort); testVector.SetMacDestination(sTestMacDestinationDefaultShort); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fd00:cafe:face:1234:abcd:ef01:2345:6789", "fd00:cafe:face:1234:c31d:a702:0d41:beef"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0xd5, 0x00, 0x3a, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xc3, 0x1d, 0xa7, 0x02, 0x0d, 0x41, 0xbe, 0xef}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform decompression test only. Test(testVector, false, true); } static void TestStatefulSource16bitDestination16bitContext0(void) { TestIphcVector testVector("Stateful compression source and destination addresses 16-bit, context 0"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultShort); testVector.SetMacDestination(sTestMacDestinationDefaultShort); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fd00:cafe:face:1234::ff:fe00:fffc", "fd00:cafe:face:1234::ff:fe00:fffe"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x66, 0x3a, 0xff, 0xfc, 0xff, 0xfe}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestStatefulCompressableLongAddressesContext0(void) { TestIphcVector testVector("Stateful compression compressible long addresses, context 0"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultLong); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fd00:cafe:face:1234:0200:5eef:1022:1100", "fd00:cafe:face:1234:0200:5eef:10aa:bbcc"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x77, 0x3a}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestStatefulCompressableShortAddressesContext0(void) { TestIphcVector testVector("Stateful compression compressible short addresses, context 0"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultShort); testVector.SetMacDestination(sTestMacDestinationDefaultShort); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fd00:cafe:face:1234::ff:fe00:0000", "fd00:cafe:face:1234::ff:fe00:c003"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x77, 0x3a}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestStatefulCompressableLongShortAddressesContext0(void) { TestIphcVector testVector("Stateful compression compressible long and short addresses, context 0"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultShort); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fd00:cafe:face:1234:0200:5eef:1022:1100", "fd00:cafe:face:1234::ff:fe00:c003"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x77, 0x3a}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestStatefulSource64bitDestination128bitContext1(void) { TestIphcVector testVector("Stateful compression source addresses 64-bit and destination inline, context 1"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultShort); testVector.SetMacDestination(sTestMacDestinationDefaultShort); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "2001:2:0:1:abcd:ef01:2345:6789", "2001:2:0:3:c31d:a702:0d41:beef"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0xd0, 0x10, 0x3a, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0x20, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0xc3, 0x1d, 0xa7, 0x02, 0x0d, 0x41, 0xbe, 0xef}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestStatefulSource64bitDestination64bitContext1(void) { TestIphcVector testVector("Stateful compression source and destination addresses 64-bit, context 1"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultShort); testVector.SetMacDestination(sTestMacDestinationDefaultShort); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "2001:2:0:1:abcd:ef01:2345:6789", "2001:2:0:1:c31d:a702:0d41:beef"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0xd5, 0x11, 0x3a, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xc3, 0x1d, 0xa7, 0x02, 0x0d, 0x41, 0xbe, 0xef}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestStatefulSourceDestinationInlineContext2CIDFalse(void) { TestIphcVector testVector("Stateful compression source and destination addresses inline, context 2 (C=FALSE)"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultShort); testVector.SetMacDestination(sTestMacDestinationDefaultShort); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "2001:2:0:2:abcd:ef01:2345:6789", "2001:2:0:2:c31d:a702:0d41:beef"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x00, 0x3a, 0x20, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0x20, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0xc3, 0x1d, 0xa7, 0x02, 0x0d, 0x41, 0xbe, 0xef}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression test only. Test(testVector, true, false); } static void TestStatefulMulticastDestination48bitContext0(void) { TestIphcVector testVector("Stateful compression multicast address, context 0"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultShort); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fd00:cafe:face:1234:0200:5eef:1022:1100", "ff33:0040:fd00:cafe:face:1234:0000:0001"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x7c, 0x3a, 0x33, 0x00, 0x00, 0x00, 0x00, 0x01}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform decompression tests. Test(testVector, true, true); } static void TestTrafficClassFlowLabel3Bytes(void) { TestIphcVector testVector("Traffic Class and Flow Label 3 bytes"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultLong); // Setup IPv6 header. testVector.SetIpHeader(0x6011ac59, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1100", "fe80::200:5eef:10aa:bbcc"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x6a, 0x33, 0x41, 0xac, 0x59, 0x3a}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestTrafficClassFlowLabel1Byte(void) { TestIphcVector testVector("Traffic Class and Flow Label 1 byte"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultLong); // Setup IPv6 header. testVector.SetIpHeader(0x60d00000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1100", "fe80::200:5eef:10aa:bbcc"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x72, 0x33, 0x43, 0x3a}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestTrafficClassFlowLabel1ByteEcnOnly(void) { TestIphcVector testVector("Traffic Class and Flow Label 1 byte with ecn only"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultLong); // Setup IPv6 header. testVector.SetIpHeader(0x60100000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1100", "fe80::200:5eef:10aa:bbcc"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x72, 0x33, 0x40, 0x3a}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestTrafficClassFlowLabelInline(void) { TestIphcVector testVector("Traffic Class and Flow Label inline"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultLong); // Setup IPv6 header. testVector.SetIpHeader(0x6ea12345, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, "fe80::200:5eef:1022:1100", "fe80::200:5eef:10aa:bbcc"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x62, 0x33, 0xBA, 0x01, 0x23, 0x45, 0x3a}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestHopLimit1(void) { TestIphcVector testVector("Hop Limit 1"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultShort); testVector.SetMacDestination(sTestMacDestinationDefaultShort); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 1, "fe80::ff:fe00:0000", "fe80::ff:fe00:c003"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x79, 0x33, 0x3a}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestHopLimit255(void) { TestIphcVector testVector("Hop Limit 255"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultShort); testVector.SetMacDestination(sTestMacDestinationDefaultShort); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 255, "fe80::ff:fe00:0000", "fe80::ff:fe00:c003"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7B, 0x33, 0x3a}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestHopLimitInline(void) { TestIphcVector testVector("Hop Limit Inline"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultShort); testVector.SetMacDestination(sTestMacDestinationDefaultShort); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 63, "fe80::ff:fe00:0000", "fe80::ff:fe00:c003"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x78, 0x33, 0x3a, 0x3f}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestUdpSourceDestinationInline(void) { TestIphcVector testVector("UDP source and destination inline"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultLong); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoUdp, 64, "fe80::200:5eef:1022:1100", "fe80::200:5eef:10aa:bbcc"); // Setup UDP header. testVector.SetUDPHeader(5683, 5684, sizeof(sTestPayloadDefault) + 8, 0xbeef); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7e, 0x33, 0xf0, 0x16, 0x33, 0x16, 0x34, 0xbe, 0xef}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(48); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestUdpSourceInlineDestination8bit(void) { TestIphcVector testVector("UDP source inline destination 8-bit"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultLong); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoUdp, 64, "fe80::200:5eef:1022:1100", "fe80::200:5eef:10aa:bbcc"); // Setup UDP header. testVector.SetUDPHeader(5683, 61441, sizeof(sTestPayloadDefault) + 8, 0xbeef); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7e, 0x33, 0xf1, 0x16, 0x33, 0x01, 0xbe, 0xef}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(48); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestUdpSource8bitDestinationInline(void) { TestIphcVector testVector("UDP source 8-bit destination 8-bit"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultLong); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoUdp, 64, "fe80::200:5eef:1022:1100", "fe80::200:5eef:10aa:bbcc"); // Setup UDP header. testVector.SetUDPHeader(61695, 5683, sizeof(sTestPayloadDefault) + 8, 0xbeef); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7e, 0x33, 0xf2, 0xff, 0x16, 0x33, 0xbe, 0xef}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(48); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestUdpFullyCompressed(void) { TestIphcVector testVector("UDP fully compressed"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultLong); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoUdp, 64, "fe80::200:5eef:1022:1100", "fe80::200:5eef:10aa:bbcc"); // Setup UDP header. testVector.SetUDPHeader(61616, 61631, sizeof(sTestPayloadDefault) + 8, 0xface); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7e, 0x33, 0xf3, 0x0f, 0xfa, 0xce}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(48); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestUdpFullyCompressedMulticast(void) { TestIphcVector testVector("UDP fully compressed with IP multicast"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultLong); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoUdp, 64, "fe80::200:5eef:1022:1100", "ff02::1"); // Setup UDP header. testVector.SetUDPHeader(61616, 61631, sizeof(sTestPayloadDefault) + 8, 0xface); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7e, 0x3b, 0x01, 0xf3, 0x0f, 0xfa, 0xce}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(48); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestUdpWithoutNhc(void) { TestIphcVector testVector("UDP without LOWPAN_NHC compression"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultShort); testVector.SetMacDestination(sTestMacDestinationDefaultShort); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoUdp, 64, "fe80::ff:fe00:0000", "fe80::ff:fe00:c003"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x33, 0x11}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(40); testVector.SetError(kErrorNone); // Perform only decompression test. Test(testVector, false, true); } static void TestExtensionHeaderHopByHopNoPadding(void) { TestIphcVector testVector("Extension Header - Hop-by-Hop with no padding"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultShort); testVector.SetMacDestination(sTestMacDestinationBroadcast); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoHopOpts, 64, "fd00:cafe:face:1234::ff:fe00:0000", "ff03::1"); // Setup extension header. uint8_t extHeader[] = {0x3a, 0x00, 0x6d, 0x04, 0x60, 0x11, 0x00, 0x0c}; testVector.SetExtHeader(extHeader, sizeof(extHeader)); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x3a, 0x06, 0x6d, 0x04, 0x60, 0x11, 0x00, 0x0c}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(48); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestExtensionHeaderHopByHopPad1(void) { TestIphcVector testVector("Extension Header - Hop-by-Hop with Pad1"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultShort); testVector.SetMacDestination(sTestMacDestinationBroadcast); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoHopOpts, 64, "fd00:cafe:face:1234::ff:fe00:0000", "ff03::1"); // Setup extension header. uint8_t extHeader[] = {0x3a, 0x00, 0x6d, 0x03, 0x60, 0x11, 0x00, 0x00}; testVector.SetExtHeader(extHeader, sizeof(extHeader)); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x3a, 0x05, 0x6d, 0x03, 0x60, 0x11, 0x00}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(48); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestExtensionHeaderHopByHopPadN2(void) { TestIphcVector testVector("Extension Header - Hop-by-Hop with PadN2"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultShort); testVector.SetMacDestination(sTestMacDestinationBroadcast); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoHopOpts, 64, "fd00:cafe:face:1234::ff:fe00:0000", "ff03::1"); // Setup extension header. uint8_t extHeader[] = {0x3a, 0x00, 0x6d, 0x02, 0x60, 0x11, 0x01, 0x00}; testVector.SetExtHeader(extHeader, sizeof(extHeader)); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x3a, 0x04, 0x6d, 0x02, 0x60, 0x11}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(48); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestExtensionHeaderHopByHopPadN3(void) { TestIphcVector testVector("Extension Header - Hop-by-Hop with PadN3"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultShort); testVector.SetMacDestination(sTestMacDestinationBroadcast); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoHopOpts, 64, "fd00:cafe:face:1234::ff:fe00:0000", "ff03::1"); // Setup extension header. uint8_t extHeader[] = {0x3a, 0x00, 0x6d, 0x01, 0x60, 0x01, 0x01, 0x00}; testVector.SetExtHeader(extHeader, sizeof(extHeader)); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x3a, 0x03, 0x6d, 0x01, 0x60}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(48); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestExtensionHeaderHopByHopPadN4(void) { TestIphcVector testVector("Extension Header - Hop-by-Hop with PadN4"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultShort); testVector.SetMacDestination(sTestMacDestinationBroadcast); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoHopOpts, 64, "fd00:cafe:face:1234::ff:fe00:0000", "ff03::1"); // Setup extension header. uint8_t extHeader[] = {0x3a, 0x00, 0x6d, 0x00, 0x01, 0x02, 0x00, 0x00}; testVector.SetExtHeader(extHeader, sizeof(extHeader)); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x3a, 0x02, 0x6d, 0x00}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(48); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestExtensionHeaderHopByHopPadN5(void) { TestIphcVector testVector("Extension Header - Hop-by-Hop with PadN5"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultShort); testVector.SetMacDestination(sTestMacDestinationBroadcast); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 16, Ip6::kProtoHopOpts, 64, "fd00:cafe:face:1234::ff:fe00:0000", "ff03::1"); // Setup extension header. uint8_t extHeader[] = {0x3a, 0x01, 0x6d, 0x07, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x33, 0x01, 0x03, 0x00, 0x00, 0x00}; testVector.SetExtHeader(extHeader, sizeof(extHeader)); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x3a, 0x09, 0x6d, 0x07, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x33}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(56); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestExtensionHeaderHopByHopPadN6(void) { TestIphcVector testVector("Extension Header - Hop-by-Hop with PadN6"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultShort); testVector.SetMacDestination(sTestMacDestinationBroadcast); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 24, Ip6::kProtoHopOpts, 64, "fd00:cafe:face:1234::ff:fe00:0000", "ff03::1"); // Setup extension header. uint8_t extHeader[] = {0x3a, 0x02, 0x6d, 0x0e, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x33, 0x01, 0x03, 0x00, 0x00, 0x00, 0x11, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00}; testVector.SetExtHeader(extHeader, sizeof(extHeader)); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x3a, 0x10, 0x6d, 0x0e, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x33, 0x01, 0x03, 0x00, 0x00, 0x00, 0x11, 0x00}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(64); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestExtensionHeaderHopByHopPadN7(void) { TestIphcVector testVector("Extension Header - Hop-by-Hop with PadN7"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultShort); testVector.SetMacDestination(sTestMacDestinationBroadcast); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 24, Ip6::kProtoHopOpts, 64, "fd00:cafe:face:1234::ff:fe00:0000", "ff03::1"); // Setup extension header. uint8_t extHeader[] = {0x3a, 0x02, 0x6d, 0x0d, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x33, 0x01, 0x03, 0x00, 0x00, 0x00, 0x11, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00}; testVector.SetExtHeader(extHeader, sizeof(extHeader)); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x3a, 0x0f, 0x6d, 0x0d, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x33, 0x01, 0x03, 0x00, 0x00, 0x00, 0x11}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(64); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestExtensionHeaderHopByHopPadN2UdpFullyCompressed(void) { TestIphcVector testVector("Extension Header - Hop-by-Hop with PadN2 and UDP"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultShort); testVector.SetMacDestination(sTestMacDestinationBroadcast); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 16, Ip6::kProtoHopOpts, 64, "fd00:cafe:face:1234::ff:fe00:0000", "ff03::1"); // Setup extension header. uint8_t extHeader[] = {0x11, 0x00, 0x6d, 0x02, 0x60, 0x11, 0x01, 0x00}; testVector.SetExtHeader(extHeader, sizeof(extHeader)); // Setup UDP header. testVector.SetUDPHeader(61616, 61631, sizeof(sTestPayloadDefault) + 8, 0xface); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe1, 0x04, 0x6d, 0x02, 0x60, 0x11, 0xf3, 0x0f, 0xfa, 0xce}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(56); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestIpInIpHopByHopPadN2UdpSourceDestinationInline(void) { TestIphcVector testVector("IP-in-IP with Hop-by-Hop with PadN2 and UDP"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultShort); testVector.SetMacDestination(sTestMacDestinationBroadcast); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 56, Ip6::kProtoHopOpts, 64, "fd00:cafe:face:1234::ff:fe00:0000", "ff03::fc"); // Setup extension header. uint8_t extHeader[] = {0x29, 0x00, 0x6d, 0x02, 0x00, 0x11, 0x01, 0x00}; testVector.SetExtHeader(extHeader, sizeof(extHeader)); // Setup IPv6 tunneled header. testVector.SetIpTunneledHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoUdp, 64, "fd00:cafe:face:1234::ff:fe00:0000", "ff05::1"); // Setup UDP header. testVector.SetUDPHeader(5683, 5684, sizeof(sTestPayloadDefault) + 8, 0xbeef); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0xfc, 0xe1, 0x04, 0x6d, 0x02, 0x00, 0x11, 0xee, 0x7e, 0x7a, 0x05, 0x00, 0x00, 0x01, 0xf0, 0x16, 0x33, 0x16, 0x34, 0xbe, 0xef}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(96); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestIpInIpWithoutExtensionHeader(void) { TestIphcVector testVector("IP-in-IP without extension header"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultLong); // Setup IPv6 header. testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 40, Ip6::kProtoIp6, 64, "fe80::200:5eef:1022:1100", "ff03::1"); // Setup IPv6 tunneled header. testVector.SetIpTunneledHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 1, "fe80::200:5eef:1022:1100", "fe80::200:5eef:10aa:bbcc"); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7e, 0x3a, 0x03, 0x00, 0x00, 0x01, 0xee, 0x79, 0x33, 0x3a}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); testVector.SetPayloadOffset(80); testVector.SetError(kErrorNone); // Perform compression and decompression tests. Test(testVector, true, true); } static void TestErrorNoIphcDispatch(void) { TestIphcVector testVector("Invalid dispatch"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultLong); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x40, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetError(kErrorParse); // Perform decompression test. Test(testVector, false, true); } static void TestErrorTruncatedIphc(void) { TestIphcVector testVector("Truncated LOWPAN_IPHC"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultLong); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x00}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetError(kErrorParse); // Perform decompression test. Test(testVector, false, true); } static void TestErrorReservedValueDestination0100(void) { TestIphcVector testVector("Reserved value of M-DAC-DAM - 0100"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultLong); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x34, 0x3A}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetError(kErrorParse); // Perform decompression test. Test(testVector, false, true); } static void TestErrorReservedValueDestination1101(void) { TestIphcVector testVector("Reserved value of M-DAC-DAM - 1101"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultLong); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x3D, 0x3A}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetError(kErrorParse); // Perform decompression test. Test(testVector, false, true); } static void TestErrorReservedValueDestination1110(void) { TestIphcVector testVector("Reserved value of M-DAC-DAM - 1110"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultLong); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x3E, 0x3A}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetError(kErrorParse); // Perform decompression test. Test(testVector, false, true); } static void TestErrorReservedValueDestination1111(void) { TestIphcVector testVector("Reserved value of M-DAC-DAM - 1111"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultLong); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7a, 0x3F, 0x3A}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetError(kErrorParse); // Perform decompression test. Test(testVector, false, true); } static void TestErrorUnknownNhc(void) { TestIphcVector testVector("Unknown value of LOWPAN_NHC ID"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultLong); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7e, 0x33, 0x00}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetError(kErrorParse); // Perform decompression test. Test(testVector, false, true); } static void TestErrorReservedNhc5(void) { TestIphcVector testVector("Reserved value of LOWPAN_NHC EID - 0x05"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultLong); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7e, 0x33, 0xea}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetError(kErrorParse); // Perform decompression test. Test(testVector, false, true); } static void TestErrorReservedNhc6(void) { TestIphcVector testVector("Reserved value of LOWPAN_NHC EID - 0x06"); // Setup MAC addresses. testVector.SetMacSource(sTestMacSourceDefaultLong); testVector.SetMacDestination(sTestMacDestinationDefaultLong); // Set LOWPAN_IPHC header. uint8_t iphc[] = {0x7e, 0x33, 0xec}; testVector.SetIphcHeader(iphc, sizeof(iphc)); // Set payload and error. testVector.SetError(kErrorParse); // Perform decompression test. Test(testVector, false, true); } /*************************************************************************************************** * @section Main test. **************************************************************************************************/ void TestLowpanIphc(void) { sInstance = testInitInstance(); VerifyOrQuit(sInstance != nullptr, "nullptr instance"); sIp6 = &sInstance->Get(); sLowpan = &sInstance->Get(); Init(); // Stateless unicast addresses compression / decompression tests. TestFullyCompressableLongAddresses(); TestFullyCompressableShortAddresses(); TestFullyCompressableShortLongAddresses(); TestFullyCompressableLongShortAddresses(); TestSourceUnspecifiedAddress(); TestSource128bitDestination128bitAddresses(); TestSource64bitDestination64bitLongAddresses(); TestSource64bitDestination64bitShortAddresses(); TestSource16bitDestination16bitAddresses(); TestSourceCompressedDestination16bitAddresses(); TestSourceCompressedDestination128bitAddresses(); // Stateless multicast addresses compression / decompression tests. TestMulticast128bitAddress(); TestMulticast48bitAddress(); TestMulticast32bitAddress(); TestMulticast8bitAddress(); // Stateful unicast addresses compression / decompression tests. TestStatefulSource64bitDestination64bitContext0(); TestStatefulSource64bitDestination64bitContext0IfContextInLine(); TestStatefulSource16bitDestination16bitContext0(); TestStatefulCompressableLongAddressesContext0(); TestStatefulCompressableShortAddressesContext0(); TestStatefulCompressableLongShortAddressesContext0(); TestStatefulSource64bitDestination128bitContext1(); TestStatefulSource64bitDestination64bitContext1(); TestStatefulSourceDestinationInlineContext2CIDFalse(); // Stateful multicast addresses compression / decompression tests. TestStatefulMulticastDestination48bitContext0(); // Traffic Class and Flow Label compression / decompression tests. TestTrafficClassFlowLabel3Bytes(); TestTrafficClassFlowLabel1Byte(); TestTrafficClassFlowLabel1ByteEcnOnly(); TestTrafficClassFlowLabelInline(); // Hop Limit compression / decompression tests. TestHopLimit1(); TestHopLimit255(); TestHopLimitInline(); // UDP compression / decompression tests. TestUdpSourceDestinationInline(); TestUdpSourceInlineDestination8bit(); TestUdpSource8bitDestinationInline(); TestUdpFullyCompressed(); TestUdpFullyCompressedMulticast(); TestUdpWithoutNhc(); // Extension Headers compression / decompression tests. TestExtensionHeaderHopByHopNoPadding(); TestExtensionHeaderHopByHopPad1(); TestExtensionHeaderHopByHopPadN2(); TestExtensionHeaderHopByHopPadN3(); TestExtensionHeaderHopByHopPadN4(); TestExtensionHeaderHopByHopPadN5(); TestExtensionHeaderHopByHopPadN6(); TestExtensionHeaderHopByHopPadN7(); TestExtensionHeaderHopByHopPadN2UdpFullyCompressed(); // IP-in-IP compression / decompression tests. TestIpInIpHopByHopPadN2UdpSourceDestinationInline(); TestIpInIpWithoutExtensionHeader(); // Invalid frame to be decompressed. TestErrorNoIphcDispatch(); TestErrorTruncatedIphc(); TestErrorReservedValueDestination0100(); TestErrorReservedValueDestination1101(); TestErrorReservedValueDestination1110(); TestErrorReservedValueDestination1111(); TestErrorUnknownNhc(); TestErrorReservedNhc5(); TestErrorReservedNhc6(); testFreeInstance(sInstance); } void TestLowpanMeshHeader(void) { enum { kMaxFrameSize = 127, kSourceAddr = 0x100, kDestAddr = 0x200, }; const uint8_t kMeshHeader1[] = {0xb1, 0x01, 0x00, 0x02, 0x00}; // src:0x100, dest:0x200, hop:0x1 const uint8_t kMeshHeader2[] = {0xbf, 0x20, 0x01, 0x00, 0x02, 0x00}; // src:0x100, dest:0x200, hop:0x20 const uint8_t kMeshHeader3[] = {0xbf, 0x01, 0x01, 0x00, 0x02, 0x00}; // src:0x100, dest:0x200, hop:0x1 (deepHops) uint8_t frame[kMaxFrameSize]; uint16_t length; FrameData frameData; FrameBuilder frameBuilder; Lowpan::MeshHeader meshHeader; meshHeader.Init(kSourceAddr, kDestAddr, 1); VerifyOrQuit(meshHeader.GetSource() == kSourceAddr, "failed after Init()"); VerifyOrQuit(meshHeader.GetDestination() == kDestAddr, "failed after Init()"); VerifyOrQuit(meshHeader.GetHopsLeft() == 1, "failed after Init()"); frameBuilder.Init(frame, sizeof(frame)); SuccessOrQuit(meshHeader.AppendTo(frameBuilder)); length = frameBuilder.GetLength(); VerifyOrQuit(length == meshHeader.GetHeaderLength()); VerifyOrQuit(length == sizeof(kMeshHeader1), "MeshHeader::AppendTo() returned length is incorrect"); VerifyOrQuit(memcmp(frame, kMeshHeader1, length) == 0, "MeshHeader::AppendTo() failed"); memset(&meshHeader, 0, sizeof(meshHeader)); frameData.Init(frame, length); VerifyOrQuit(Lowpan::MeshHeader::IsMeshHeader(frameData)); SuccessOrQuit(meshHeader.ParseFrom(frameData)); VerifyOrQuit(frameData.GetLength() == 0, "ParseFrom() did not skip over parsed content"); VerifyOrQuit(frameData.GetBytes() - frame == length, "ParseFrom() did not skip over parsed content"); VerifyOrQuit(meshHeader.GetSource() == kSourceAddr, "failed after ParseFrom()"); VerifyOrQuit(meshHeader.GetDestination() == kDestAddr, "failed after ParseFrom()"); VerifyOrQuit(meshHeader.GetHopsLeft() == 1, "failed after ParseFrom()"); frameData.Init(frame, length - 1); VerifyOrQuit(meshHeader.ParseFrom(frameData) == kErrorParse, "MeshHeader::ParseFrom() did not fail with incorrect length"); //- - - - - - - - - - - - - - - - - - - - - - - - - - meshHeader.Init(kSourceAddr, kDestAddr, 0x20); VerifyOrQuit(meshHeader.GetSource() == kSourceAddr, "failed after Init()"); VerifyOrQuit(meshHeader.GetDestination() == kDestAddr, "failed after Init()"); VerifyOrQuit(meshHeader.GetHopsLeft() == 0x20, "failed after Init()"); frameBuilder.Init(frame, sizeof(frame)); SuccessOrQuit(meshHeader.AppendTo(frameBuilder)); length = frameBuilder.GetLength(); VerifyOrQuit(length == sizeof(kMeshHeader2), "MeshHeader::AppendTo() returned length is incorrect"); VerifyOrQuit(length == meshHeader.GetHeaderLength()); VerifyOrQuit(memcmp(frame, kMeshHeader2, length) == 0, "MeshHeader::AppendTo() failed"); memset(&meshHeader, 0, sizeof(meshHeader)); frameData.Init(frame, length); VerifyOrQuit(Lowpan::MeshHeader::IsMeshHeader(frameData)); SuccessOrQuit(meshHeader.ParseFrom(frameData)); VerifyOrQuit(frameData.GetLength() == 0, "ParseFrom() did not skip over parsed content"); VerifyOrQuit(frameData.GetBytes() - frame == length, "ParseFrom() did not skip over parsed content"); VerifyOrQuit(meshHeader.GetSource() == kSourceAddr, "failed after ParseFrom()"); VerifyOrQuit(meshHeader.GetDestination() == kDestAddr, "failed after ParseFrom()"); VerifyOrQuit(meshHeader.GetHopsLeft() == 0x20, "failed after ParseFrom()"); frameData.Init(frame, length - 1); VerifyOrQuit(meshHeader.ParseFrom(frameData) == kErrorParse, "MeshHeader::ParseFrom() did not fail with incorrect length"); //- - - - - - - - - - - - - - - - - - - - - - - - - - length = sizeof(kMeshHeader3); frameData.Init(kMeshHeader3, sizeof(kMeshHeader3)); SuccessOrQuit(meshHeader.ParseFrom(frameData)); VerifyOrQuit(frameData.GetLength() == 0, "ParseFrom() did not skip over parsed content"); VerifyOrQuit(frameData.GetBytes() - kMeshHeader3 == length, "ParseFrom() did not skip over parsed content"); VerifyOrQuit(meshHeader.GetSource() == kSourceAddr, "failed after ParseFrom()"); VerifyOrQuit(meshHeader.GetDestination() == kDestAddr, "failed after ParseFrom()"); VerifyOrQuit(meshHeader.GetHopsLeft() == 1, "failed after ParseFrom()"); frameBuilder.Init(frame, sizeof(frame)); SuccessOrQuit(meshHeader.AppendTo(frameBuilder)); VerifyOrQuit(frameBuilder.GetLength() == sizeof(kMeshHeader1)); frameData.Init(kMeshHeader3, sizeof(kMeshHeader3) - 1); VerifyOrQuit(meshHeader.ParseFrom(frameData) == kErrorParse, "MeshHeader::ParseFrom() did not fail with incorrect length"); } void TestLowpanFragmentHeader(void) { static constexpr uint16_t kMaxFrameSize = 127; static constexpr uint16_t kSize = 0x7ef; static constexpr uint16_t kTag = 0x1234; static constexpr uint16_t kOffset = (100 * 8); const uint8_t kFragHeader1[] = {0xc7, 0xef, 0x12, 0x34}; // size:0x7ef, tag:0x1234, offset:0 (first frag) const uint8_t kFragHeader2[] = {0xe7, 0xef, 0x12, 0x34, 0x64}; // size:0x7ef, tag:0x1234, offset:100 (next frag) const uint8_t kFragHeader3[] = {0xe7, 0xef, 0x12, 0x34, 0x00}; // size:0x7ef, tag:0x1234, offset:0 (next frag) const uint8_t kInvalidFragHeader1[] = {0xe8, 0xef, 0x12, 0x34, 0x64}; const uint8_t kInvalidFragHeader2[] = {0xd0, 0xef, 0x12, 0x34, 0x64}; const uint8_t kInvalidFragHeader3[] = {0x90, 0xef, 0x12, 0x34, 0x64}; uint8_t frame[kMaxFrameSize]; uint16_t length; FrameData frameData; FrameBuilder frameBuilder; Lowpan::FragmentHeader fragHeader; Lowpan::FragmentHeader::FirstFrag firstFragHeader; Lowpan::FragmentHeader::NextFrag nextFragHeader; frameBuilder.Init(frame, sizeof(frame)); firstFragHeader.Init(kSize, kTag); SuccessOrQuit(frameBuilder.Append(firstFragHeader)); length = frameBuilder.GetLength(); VerifyOrQuit(length == sizeof(Lowpan::FragmentHeader::FirstFrag)); VerifyOrQuit(memcmp(frame, kFragHeader1, length) == 0); memset(&fragHeader, 0, sizeof(fragHeader)); frameData.Init(frame, length); VerifyOrQuit(Lowpan::FragmentHeader::IsFragmentHeader(frameData)); SuccessOrQuit(fragHeader.ParseFrom(frameData)); VerifyOrQuit(frameData.GetLength() == 0, "ParseFrom() did not skip over parsed content"); VerifyOrQuit(frameData.GetBytes() - frame == length, "ParseFrom() did not skip over parsed content"); VerifyOrQuit(fragHeader.GetDatagramSize() == kSize, "failed after ParseFrom()"); VerifyOrQuit(fragHeader.GetDatagramTag() == kTag, "failed after ParseFrom()"); VerifyOrQuit(fragHeader.GetDatagramOffset() == 0, "failed after ParseFrom()"); frameData.Init(frame, length - 1); VerifyOrQuit(fragHeader.ParseFrom(frameData) == kErrorParse, "FragmentHeader::ParseFrom() did not fail with incorrect length"); VerifyOrQuit(frameData.GetLength() == length - 1); VerifyOrQuit(frameData.GetBytes() == frame); //- - - - - - - - - - - - - - - - - - - - - - - - - - frameBuilder.Init(frame, sizeof(frame)); nextFragHeader.Init(kSize, kTag, kOffset); SuccessOrQuit(frameBuilder.Append(nextFragHeader)); length = frameBuilder.GetLength(); VerifyOrQuit(length == sizeof(kFragHeader2)); VerifyOrQuit(memcmp(frame, kFragHeader2, length) == 0); // Check the truncation of offset (to be multiple of 8). frameBuilder.Init(frame, sizeof(frame)); nextFragHeader.Init(kSize, kTag, kOffset + 1); SuccessOrQuit(frameBuilder.Append(nextFragHeader)); length = frameBuilder.GetLength(); VerifyOrQuit(length == sizeof(kFragHeader2)); VerifyOrQuit(memcmp(frame, kFragHeader2, length) == 0); frameBuilder.Init(frame, sizeof(frame)); nextFragHeader.Init(kSize, kTag, kOffset + 7); SuccessOrQuit(frameBuilder.Append(nextFragHeader)); length = frameBuilder.GetLength(); VerifyOrQuit(length == sizeof(kFragHeader2)); VerifyOrQuit(memcmp(frame, kFragHeader2, length) == 0); memset(&fragHeader, 0, sizeof(fragHeader)); frameData.Init(frame, length); VerifyOrQuit(Lowpan::FragmentHeader::IsFragmentHeader(frameData)); SuccessOrQuit(fragHeader.ParseFrom(frameData)); VerifyOrQuit(frameData.GetLength() == 0, "ParseFrom() did not skip over parsed content"); VerifyOrQuit(frameData.GetBytes() - frame == length, "ParseFrom() did not skip over parsed content"); VerifyOrQuit(fragHeader.GetDatagramSize() == kSize, "failed after ParseFrom()"); VerifyOrQuit(fragHeader.GetDatagramTag() == kTag, "failed after ParseFrom()"); VerifyOrQuit(fragHeader.GetDatagramOffset() == kOffset, "failed after ParseFrom()"); frameData.Init(frame, length - 1); VerifyOrQuit(fragHeader.ParseFrom(frameData) == kErrorParse, "FragmentHeader::ParseFrom() did not fail with incorrect length"); VerifyOrQuit(frameData.GetLength() == length - 1); VerifyOrQuit(frameData.GetBytes() == frame); //- - - - - - - - - - - - - - - - - - - - - - - - - - length = sizeof(kFragHeader3); memcpy(frame, kFragHeader3, length); frameData.Init(frame, length); SuccessOrQuit(fragHeader.ParseFrom(frameData)); VerifyOrQuit(frameData.GetLength() == 0, "ParseFrom() did not skip over parsed content"); VerifyOrQuit(frameData.GetBytes() - frame == length, "ParseFrom() did not skip over parsed content"); VerifyOrQuit(fragHeader.GetDatagramSize() == kSize, "failed after ParseFrom()"); VerifyOrQuit(fragHeader.GetDatagramTag() == kTag, "failed after ParseFrom()"); VerifyOrQuit(fragHeader.GetDatagramOffset() == 0, "failed after ParseFrom()"); frameData.Init(frame, length - 1); VerifyOrQuit(fragHeader.ParseFrom(frameData) == kErrorParse, "FragmentHeader::ParseFrom() did not fail with incorrect length"); VerifyOrQuit(frameData.GetLength() == length - 1); VerifyOrQuit(frameData.GetBytes() == frame); //- - - - - - - - - - - - - - - - - - - - - - - - - - length = sizeof(kInvalidFragHeader1); memcpy(frame, kInvalidFragHeader1, length); frameData.Init(frame, length); VerifyOrQuit(!Lowpan::FragmentHeader::IsFragmentHeader(frameData), "IsFragmentHeader() did not detect invalid header"); VerifyOrQuit(fragHeader.ParseFrom(frameData) != kErrorNone, "FragmentHeader::ParseFrom() did not fail with invalid header"); VerifyOrQuit(frameData.GetLength() == length); VerifyOrQuit(frameData.GetBytes() == frame); length = sizeof(kInvalidFragHeader2); memcpy(frame, kInvalidFragHeader2, length); frameData.Init(frame, length); VerifyOrQuit(!Lowpan::FragmentHeader::IsFragmentHeader(frameData), "IsFragmentHeader() did not detect invalid header"); VerifyOrQuit(fragHeader.ParseFrom(frameData) != kErrorNone, "FragmentHeader::ParseFrom() did not fail with invalid header"); VerifyOrQuit(frameData.GetLength() == length); VerifyOrQuit(frameData.GetBytes() == frame); length = sizeof(kInvalidFragHeader3); memcpy(frame, kInvalidFragHeader3, length); frameData.Init(frame, length); VerifyOrQuit(!Lowpan::FragmentHeader::IsFragmentHeader(frameData), "IsFragmentHeader() did not detect invalid header"); VerifyOrQuit(fragHeader.ParseFrom(frameData) != kErrorNone, "FragmentHeader::ParseFrom() did not fail with invalid header"); VerifyOrQuit(frameData.GetLength() == length); VerifyOrQuit(frameData.GetBytes() == frame); } } // namespace ot int main(void) { ot::TestLowpanIphc(); ot::TestLowpanMeshHeader(); ot::TestLowpanFragmentHeader(); printf("All tests passed\n"); return 0; }