From 78156bbdcd89839b18e8f0dd2174aaca4c90236b Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Mon, 6 Jan 2020 14:52:14 -0800 Subject: [PATCH] [unit-test] add unit test for Mesh/Fragment Header (#4453) --- tests/unit/test_lowpan.cpp | 192 +++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) diff --git a/tests/unit/test_lowpan.cpp b/tests/unit/test_lowpan.cpp index 24a1c8e06..1eb8772a9 100644 --- a/tests/unit/test_lowpan.cpp +++ b/tests/unit/test_lowpan.cpp @@ -1832,11 +1832,203 @@ void TestLowpanIphc(void) 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; + uint16_t headerLength; + Lowpan::MeshHeader meshHeader; + + meshHeader.Init(kSourceAddr, kDestAddr, 1); + VerifyOrQuit(meshHeader.GetSource() == kSourceAddr, "MeshHeader::GetSource() failed after Init()"); + VerifyOrQuit(meshHeader.GetDestination() == kDestAddr, "MeshHeader::GetDestination() failed after Init()"); + VerifyOrQuit(meshHeader.GetHopsLeft() == 1, "MeshHeader::GetHopsLeft() failed after Init()"); + + length = meshHeader.WriteTo(frame); + VerifyOrQuit(length == meshHeader.GetHeaderLength(), "MeshHeader::GetHeaderLength() failed"); + VerifyOrQuit(length == sizeof(kMeshHeader1), "MeshHeader::WriteTo() returned length is incorrect"); + VerifyOrQuit(memcmp(frame, kMeshHeader1, length) == 0, "MeshHeader::WriteTo() failed"); + + memset(&meshHeader, 0, sizeof(meshHeader)); + VerifyOrQuit(Lowpan::MeshHeader::IsMeshHeader(frame, length), "IsMeshHeader() failed"); + SuccessOrQuit(meshHeader.ParseFrom(frame, length, headerLength), "MeshHeader::ParseFrom() failed"); + VerifyOrQuit(headerLength == length, "MeshHeader::ParseFrom() returned length is incorrect"); + VerifyOrQuit(meshHeader.GetSource() == kSourceAddr, "MeshHeader::GetSource() failed after ParseFrom()"); + VerifyOrQuit(meshHeader.GetDestination() == kDestAddr, "MeshHeader::GetDestination() failed after ParseFrom()"); + VerifyOrQuit(meshHeader.GetHopsLeft() == 1, "MeshHeader::GetHopsLeft() failed after ParseFrom()"); + + VerifyOrQuit(meshHeader.ParseFrom(frame, length - 1, headerLength) == OT_ERROR_PARSE, + "MeshHeader::ParseFrom() did not fail with incorrect length"); + + //- - - - - - - - - - - - - - - - - - - - - - - - - - + + meshHeader.Init(kSourceAddr, kDestAddr, 0x20); + VerifyOrQuit(meshHeader.GetSource() == kSourceAddr, "MeshHeader::GetSource() failed after Init()"); + VerifyOrQuit(meshHeader.GetDestination() == kDestAddr, "MeshHeader::GetDestination() failed after Init()"); + VerifyOrQuit(meshHeader.GetHopsLeft() == 0x20, "MeshHeader::GetHopsLeft() failed after Init()"); + + length = meshHeader.WriteTo(frame); + VerifyOrQuit(length == sizeof(kMeshHeader2), "MeshHeader::WriteTo() returned length is incorrect"); + VerifyOrQuit(length == meshHeader.GetHeaderLength(), "MeshHeader::GetHeaderLength() failed"); + VerifyOrQuit(memcmp(frame, kMeshHeader2, length) == 0, "MeshHeader::WriteTo() failed"); + + memset(&meshHeader, 0, sizeof(meshHeader)); + VerifyOrQuit(Lowpan::MeshHeader::IsMeshHeader(frame, length), "IsMeshHeader() failed"); + SuccessOrQuit(meshHeader.ParseFrom(frame, length, headerLength), "MeshHeader::ParseFrom() failed"); + VerifyOrQuit(headerLength == length, "MeshHeader::ParseFrom() returned length is incorrect"); + VerifyOrQuit(meshHeader.GetSource() == kSourceAddr, "MeshHeader::GetSource() failed after ParseFrom()"); + VerifyOrQuit(meshHeader.GetDestination() == kDestAddr, "MeshHeader::GetDestination() failed after ParseFrom()"); + VerifyOrQuit(meshHeader.GetHopsLeft() == 0x20, "MeshHeader::GetHopsLeft() failed after ParseFrom()"); + + VerifyOrQuit(meshHeader.ParseFrom(frame, length - 1, headerLength) == OT_ERROR_PARSE, + "MeshHeader::ParseFrom() did not fail with incorrect length"); + + //- - - - - - - - - - - - - - - - - - - - - - - - - - + + SuccessOrQuit(meshHeader.ParseFrom(kMeshHeader3, sizeof(kMeshHeader3), headerLength), + "MeshHeader::ParseFrom() failed"); + VerifyOrQuit(headerLength == sizeof(kMeshHeader3), "MeshHeader::ParseFrom() returned length is incorrect"); + VerifyOrQuit(meshHeader.GetSource() == kSourceAddr, "MeshHeader::GetSource() failed after Init()"); + VerifyOrQuit(meshHeader.GetDestination() == kDestAddr, "MeshHeader::GetDestination() failed after Init()"); + VerifyOrQuit(meshHeader.GetHopsLeft() == 1, "MeshHeader::GetHopsLeft() failed after Init()"); + + VerifyOrQuit(meshHeader.WriteTo(frame) == sizeof(kMeshHeader1), "MeshHeader::WriteTo() failed"); + + VerifyOrQuit(meshHeader.ParseFrom(kMeshHeader3, sizeof(kMeshHeader3) - 1, headerLength) == OT_ERROR_PARSE, + "MeshHeader::ParseFrom() did not fail with incorrect length"); +} + +void TestLowpanFragmentHeader(void) +{ + enum + { + kMaxFrameSize = 127, + kSize = 0x7ef, + kTag = 0x1234, + 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; + uint16_t headerLength; + Lowpan::FragmentHeader fragHeader; + + fragHeader.InitFirstFragment(kSize, kTag); + VerifyOrQuit(fragHeader.GetDatagramSize() == kSize, "FragmentHeader::GetDatagramSize() failed after Init"); + VerifyOrQuit(fragHeader.GetDatagramTag() == kTag, "FragmentHeader::GetDatagramTag() failed after Init()"); + VerifyOrQuit(fragHeader.GetDatagramOffset() == 0, "FragmentHeader::GetDatagramOffset() failed after Init()"); + + length = fragHeader.WriteTo(frame); + VerifyOrQuit(length == Lowpan::FragmentHeader::kFirstFragmentHeaderSize, + "FragmentHeader::WriteTo() returned length is incorrect"); + VerifyOrQuit(length == sizeof(kFragHeader1), "FragmentHeader::WriteTo() returned length is incorrect"); + VerifyOrQuit(memcmp(frame, kFragHeader1, length) == 0, "FragmentHeader::WriteTo() failed"); + + memset(&fragHeader, 0, sizeof(fragHeader)); + VerifyOrQuit(Lowpan::FragmentHeader::IsFragmentHeader(frame, length), "IsFragmentHeader() failed"); + SuccessOrQuit(fragHeader.ParseFrom(frame, length, headerLength), "FragmentHeader::ParseFrom() failed"); + VerifyOrQuit(headerLength == length, "FragmentHeader::ParseFrom() returned length is incorrect"); + VerifyOrQuit(fragHeader.GetDatagramSize() == kSize, "FragmentHeader::GetDatagramSize() failed after ParseFrom()"); + VerifyOrQuit(fragHeader.GetDatagramTag() == kTag, "FragmentHeader::GetDatagramTag() failed after ParseFrom()"); + VerifyOrQuit(fragHeader.GetDatagramOffset() == 0, "FragmentHeader::GetDatagramOffset() failed after ParseFrom()"); + + VerifyOrQuit(fragHeader.ParseFrom(frame, length - 1, headerLength) == OT_ERROR_PARSE, + "FragmentHeader::ParseFrom() did not fail with incorrect length"); + + //- - - - - - - - - - - - - - - - - - - - - - - - - - + + fragHeader.Init(kSize, kTag, kOffset); + VerifyOrQuit(fragHeader.GetDatagramSize() == kSize, "FragmentHeader::GetDatagramSize() failed after Init"); + VerifyOrQuit(fragHeader.GetDatagramTag() == kTag, "FragmentHeader::GetDatagramTag() failed after Init()"); + VerifyOrQuit(fragHeader.GetDatagramOffset() == kOffset, "FragmentHeader::GetDatagramOffset() failed after Init()"); + + // Check the truncation of offset (to be multiple of 8). + fragHeader.Init(kSize, kTag, kOffset + 1); + VerifyOrQuit(fragHeader.GetDatagramOffset() == kOffset, "FragmentHeader::GetDatagramOffset() did not truncate"); + fragHeader.Init(kSize, kTag, kOffset + 7); + VerifyOrQuit(fragHeader.GetDatagramOffset() == kOffset, "FragmentHeader::GetDatagramOffset() did not truncate"); + + length = fragHeader.WriteTo(frame); + VerifyOrQuit(length == Lowpan::FragmentHeader::kSubsequentFragmentHeaderSize, + "FragmentHeader::WriteTo() returned length is incorrect"); + VerifyOrQuit(length == sizeof(kFragHeader2), "FragmentHeader::WriteTo() returned length is incorrect"); + VerifyOrQuit(memcmp(frame, kFragHeader2, length) == 0, "FragmentHeader::WriteTo() failed"); + + memset(&fragHeader, 0, sizeof(fragHeader)); + VerifyOrQuit(Lowpan::FragmentHeader::IsFragmentHeader(frame, length), "IsFragmentHeader() failed"); + SuccessOrQuit(fragHeader.ParseFrom(frame, length, headerLength), "FragmentHeader::ParseFrom() failed"); + VerifyOrQuit(headerLength == length, "FragmentHeader::ParseFrom() returned length is incorrect"); + VerifyOrQuit(fragHeader.GetDatagramSize() == kSize, "FragmentHeader::GetDatagramSize() failed after ParseFrom()"); + VerifyOrQuit(fragHeader.GetDatagramTag() == kTag, "FragmentHeader::GetDatagramTag() failed after ParseFrom()"); + VerifyOrQuit(fragHeader.GetDatagramOffset() == kOffset, + "FragmentHeader::GetDatagramOffset() failed after ParseFrom()"); + + VerifyOrQuit(fragHeader.ParseFrom(frame, length - 1, headerLength) == OT_ERROR_PARSE, + "FragmentHeader::ParseFrom() did not fail with incorrect length"); + + //- - - - - - - - - - - - - - - - - - - - - - - - - - + + length = sizeof(kFragHeader3); + memcpy(frame, kFragHeader3, length); + SuccessOrQuit(fragHeader.ParseFrom(frame, length, headerLength), "FragmentHeader::ParseFrom() failed"); + VerifyOrQuit(headerLength == length, "FragmentHeader::ParseFrom() returned length is incorrect"); + VerifyOrQuit(fragHeader.GetDatagramSize() == kSize, "FragmentHeader::GetDatagramSize() failed after ParseFrom()"); + VerifyOrQuit(fragHeader.GetDatagramTag() == kTag, "FragmentHeader::GetDatagramTag() failed after ParseFrom()"); + VerifyOrQuit(fragHeader.GetDatagramOffset() == 0, "FragmentHeader::GetDatagramOffset() failed after ParseFrom()"); + + VerifyOrQuit(fragHeader.ParseFrom(frame, length - 1, headerLength) == OT_ERROR_PARSE, + "FragmentHeader::ParseFrom() did not fail with incorrect length"); + + //- - - - - - - - - - - - - - - - - - - - - - - - - - + + length = sizeof(kInvalidFragHeader1); + memcpy(frame, kInvalidFragHeader1, length); + VerifyOrQuit(!Lowpan::FragmentHeader::IsFragmentHeader(frame, length), + "IsFragmentHeader() did not detect invalid header"); + VerifyOrQuit(fragHeader.ParseFrom(frame, length, headerLength) != OT_ERROR_NONE, + "FragmentHeader::ParseFrom() did not fail with invalid header"); + + length = sizeof(kInvalidFragHeader2); + memcpy(frame, kInvalidFragHeader2, length); + VerifyOrQuit(!Lowpan::FragmentHeader::IsFragmentHeader(frame, length), + "IsFragmentHeader() did not detect invalid header"); + VerifyOrQuit(fragHeader.ParseFrom(frame, length, headerLength) != OT_ERROR_NONE, + "FragmentHeader::ParseFrom() did not fail with invalid header"); + + length = sizeof(kInvalidFragHeader3); + memcpy(frame, kInvalidFragHeader3, length); + VerifyOrQuit(!Lowpan::FragmentHeader::IsFragmentHeader(frame, length), + "IsFragmentHeader() did not detect invalid header"); + VerifyOrQuit(fragHeader.ParseFrom(frame, length, headerLength) != OT_ERROR_NONE, + "FragmentHeader::ParseFrom() did not fail with invalid header"); +} + } // namespace ot int main(void) { TestLowpanIphc(); + TestLowpanMeshHeader(); + TestLowpanFragmentHeader(); printf("All tests passed\n"); return 0;