mirror of
https://github.com/espressif/openthread.git
synced 2026-06-05 21:14:49 +00:00
44f5cddc2e
This commit introduces the `MessageAllocator` template class using the CRTP pattern to provide a unified implementation of the `NewMessage()` methods. It standardizes the reserved header sizes for different message types within `ReservedHeaderSize`. This removes boilerplate code and redundant `NewMessage()` method implementations across the `Ip6`, `Icmp`, `Udp`, `Udp::Socket`, and `CoapBase` classes.
455 lines
20 KiB
C++
455 lines
20 KiB
C++
/*
|
|
* Copyright (c) 2022, 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 <stdio.h>
|
|
|
|
#include "test_platform.h"
|
|
#include "test_util.hpp"
|
|
|
|
#include "instance/instance.hpp"
|
|
|
|
#if OPENTHREAD_CONFIG_NAT64_TRANSLATOR_ENABLE
|
|
|
|
namespace ot {
|
|
namespace Nat64 {
|
|
|
|
#define Log(...) printf(OT_FIRST_ARG(__VA_ARGS__) "\n" OT_REST_ARGS(__VA_ARGS__))
|
|
|
|
static ot::Instance *sInstance;
|
|
|
|
void DumpIp6Message(const char *aTextMessage, const Message &aMessage)
|
|
{
|
|
Ip6::Headers ip6Headers;
|
|
|
|
Log("%s", aTextMessage);
|
|
|
|
if (ip6Headers.ParseFrom(aMessage) != kErrorNone)
|
|
{
|
|
Log(" Malformed IPv6 message");
|
|
ExitNow();
|
|
}
|
|
|
|
Log(" IPv6 Headers");
|
|
Log(" src : %s", ip6Headers.GetSourceAddress().ToString().AsCString());
|
|
Log(" dst : %s", ip6Headers.GetDestinationAddress().ToString().AsCString());
|
|
Log(" proto : %s", otIp6ProtoToString(ip6Headers.GetIpProto()));
|
|
|
|
if (ip6Headers.IsTcp() || ip6Headers.IsUdp())
|
|
{
|
|
Log(" src-port : %u", ip6Headers.GetSourcePort());
|
|
Log(" dst-port : %u", ip6Headers.GetDestinationPort());
|
|
}
|
|
else if (ip6Headers.IsIcmp6())
|
|
{
|
|
Log(" icmp6-id : %u", ip6Headers.GetIcmpHeader().GetId());
|
|
}
|
|
|
|
exit:
|
|
return;
|
|
}
|
|
|
|
void DumpIp4Message(const char *aTextMessage, const Message &aMessage)
|
|
{
|
|
Ip4::Headers ip4Headers;
|
|
|
|
Log("%s", aTextMessage);
|
|
|
|
if (ip4Headers.ParseFrom(aMessage) != kErrorNone)
|
|
{
|
|
Log(" Malformed IPv4 message");
|
|
ExitNow();
|
|
}
|
|
|
|
Log(" IPv4 Headers");
|
|
Log(" src : %s", ip4Headers.GetSourceAddress().ToString().AsCString());
|
|
Log(" dst : %s", ip4Headers.GetDestinationAddress().ToString().AsCString());
|
|
Log(" proto : %s", ip4Headers.IsIcmp4() ? "ICMP4" : otIp6ProtoToString(ip4Headers.GetIpProto()));
|
|
|
|
if (ip4Headers.IsTcp() || ip4Headers.IsUdp())
|
|
{
|
|
Log(" src-port : %u", ip4Headers.GetSourcePort());
|
|
Log(" dst-port : %u", ip4Headers.GetDestinationPort());
|
|
}
|
|
else if (ip4Headers.IsIcmp4())
|
|
{
|
|
Log(" icmp4-id : %u", ip4Headers.GetIcmpHeader().GetId());
|
|
}
|
|
|
|
exit:
|
|
return;
|
|
}
|
|
|
|
void VerifyMessage(const Message &aMessage, const uint8_t *aExpectedContent, uint16_t aExpectedLength)
|
|
{
|
|
VerifyOrQuit(aMessage.GetLength() == aExpectedLength);
|
|
VerifyOrQuit(aMessage.CompareBytes(0, aExpectedContent, aExpectedLength));
|
|
}
|
|
|
|
void Verify6To4(const char *aTestName,
|
|
const uint8_t *aIp6Message,
|
|
const uint16_t aIp6Length,
|
|
const uint8_t *aIp4Message,
|
|
uint16_t aIp4Length,
|
|
Error aError)
|
|
{
|
|
Message *message = sInstance->Get<Ip6::Ip6>().NewMessage();
|
|
Error error;
|
|
|
|
Log("- - - - - - - - - - - - - - - - - - - - - - - - - ");
|
|
Log("Translate IPv6 to IPv4: %s", aTestName);
|
|
|
|
VerifyOrQuit(message != nullptr);
|
|
SuccessOrQuit(message->AppendBytes(aIp6Message, aIp6Length));
|
|
|
|
DumpIp6Message("IPv6 message", *message);
|
|
|
|
error = sInstance->Get<Translator>().TranslateIp6ToIp4(*message);
|
|
Log("Error: %s (expecting:%s)", ErrorToString(error), ErrorToString(aError));
|
|
VerifyOrQuit(error == aError);
|
|
|
|
if (aIp4Message != nullptr)
|
|
{
|
|
DumpIp4Message("Translated IPv4 message", *message);
|
|
VerifyMessage(*message, aIp4Message, aIp4Length);
|
|
}
|
|
}
|
|
|
|
template <uint16_t kIp6Length, uint16_t kIp4Length>
|
|
void Verify6To4(const char *aTestName,
|
|
const uint8_t (&aIp6Message)[kIp6Length],
|
|
const uint8_t (&aIp4Message)[kIp4Length],
|
|
Error aError)
|
|
{
|
|
Verify6To4(aTestName, aIp6Message, kIp6Length, aIp4Message, kIp4Length, aError);
|
|
}
|
|
|
|
template <uint16_t kIp6Length>
|
|
void Verify6To4(const char *aTestName, const uint8_t (&aIp6Message)[kIp6Length], Error aError)
|
|
{
|
|
Verify6To4(aTestName, aIp6Message, kIp6Length, nullptr, 0, aError);
|
|
}
|
|
|
|
void Verify4To6(const char *aTestName,
|
|
const uint8_t *aIp4Message,
|
|
uint16_t aIp4Length,
|
|
const uint8_t *aIp6Message,
|
|
uint16_t aIp6Length,
|
|
Error aError)
|
|
{
|
|
Message *message = sInstance->Get<Ip6::Ip6>().NewMessage();
|
|
Error error;
|
|
|
|
Log("- - - - - - - - - - - - - - - - - - - - - - - - - ");
|
|
Log("Translate IPv4 to IPv6: %s", aTestName);
|
|
|
|
VerifyOrQuit(message != nullptr);
|
|
SuccessOrQuit(message->AppendBytes(aIp4Message, aIp4Length));
|
|
|
|
DumpIp4Message("IPv4 message", *message);
|
|
|
|
error = sInstance->Get<Translator>().TranslateIp4ToIp6(*message);
|
|
Log("Error: %s (expecting:%s)", ErrorToString(error), ErrorToString(aError));
|
|
VerifyOrQuit(error == aError);
|
|
|
|
if (aIp6Message != nullptr)
|
|
{
|
|
DumpIp6Message("Translated IPv6 message", *message);
|
|
VerifyMessage(*message, aIp6Message, aIp6Length);
|
|
}
|
|
}
|
|
|
|
template <uint16_t kIp4Length, uint16_t kIp6Length>
|
|
void Verify4To6(const char *aTestName,
|
|
const uint8_t (&aIp4Message)[kIp4Length],
|
|
const uint8_t (&aIp6Message)[kIp6Length],
|
|
Error aError)
|
|
{
|
|
Verify4To6(aTestName, aIp4Message, kIp4Length, aIp6Message, kIp6Length, aError);
|
|
}
|
|
|
|
template <uint16_t kIp4Length>
|
|
void Verify4To6(const char *aTestName, const uint8_t (&aIp4Message)[kIp4Length], Error aError)
|
|
{
|
|
Verify4To6(aTestName, aIp4Message, kIp4Length, nullptr, 0, aError);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
void TestNat64Translation(void)
|
|
{
|
|
Ip6::Prefix prefix;
|
|
Ip4::Cidr cidr;
|
|
|
|
Log("--------------------------------------------------------------------------------------------");
|
|
Log("TestNat64Translation");
|
|
|
|
sInstance = testInitInstance();
|
|
VerifyOrQuit(sInstance != nullptr);
|
|
|
|
SuccessOrQuit(prefix.FromString("fd01::/96"));
|
|
SuccessOrQuit(cidr.FromString("192.168.123.1/32"));
|
|
|
|
SuccessOrQuit(sInstance->Get<Translator>().SetIp4Cidr(cidr));
|
|
sInstance->Get<Translator>().SetNat64Prefix(prefix);
|
|
sInstance->Get<Translator>().SetEnabled(true);
|
|
|
|
{
|
|
// fd02::1 fd01::ac10:f3c5 UDP 52 43981 → 4660 Len=4
|
|
const uint8_t kIp6Packet[] = {
|
|
0x60, 0x08, 0x6e, 0x38, 0x00, 0x0c, 0x11, 0x40, 0xfd, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
172, 16, 243, 197, 0xab, 0xcd, 0x12, 0x34, 0x00, 0x0c, 0xe3, 0x31, 0x61, 0x62, 0x63, 0x64,
|
|
};
|
|
// 192.168.123.1 172.16.243.197 UDP 32 43981 → 4660 Len=4
|
|
const uint8_t kIp4Packet[] = {0x45, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0x9f,
|
|
0x4d, 192, 168, 123, 1, 172, 16, 243, 197, 0xab, 0xcd,
|
|
0x12, 0x34, 0x00, 0x0c, 0xa1, 0x8d, 0x61, 0x62, 0x63, 0x64};
|
|
|
|
Verify6To4("Valid v6 UDP", kIp6Packet, kIp4Packet, kErrorNone);
|
|
}
|
|
|
|
{
|
|
// 172.16.243.197 192.168.123.1 UDP 32 43981 → 4660 Len=4
|
|
const uint8_t kIp4Packet[] = {0x45, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x11, 0xa0,
|
|
0x4d, 172, 16, 243, 197, 192, 168, 123, 1, 0xab, 0xcd,
|
|
0x12, 0x34, 0x00, 0x0c, 0xa1, 0x8d, 0x61, 0x62, 0x63, 0x64};
|
|
// fd01::ac10:f3c5 fd02::1 UDP 52 43981 → 4660 Len=4
|
|
const uint8_t kIp6Packet[] = {
|
|
0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x11, 0x3f, 0xfd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 172, 16, 243, 197, 0xfd, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x01, 0xab, 0xcd, 0x12, 0x34, 0x00, 0x0c, 0xe3, 0x31, 0x61, 0x62, 0x63, 0x64,
|
|
};
|
|
|
|
Verify4To6("Valid v4 UDP", kIp4Packet, kIp6Packet, kErrorNone);
|
|
}
|
|
|
|
{
|
|
// fd02::1 fd01::ac10:f3c5 TCP 64 43981 → 4660 [ACK] Seq=1 Ack=1 Win=1 Len=4
|
|
const uint8_t kIp6Packet[] = {
|
|
0x60, 0x08, 0x6e, 0x38, 0x00, 0x18, 0x06, 0x40, 0xfd, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 172, 16, 243, 197, 0xab, 0xcd, 0x12, 0x34, 0x87, 0x65, 0x43, 0x21,
|
|
0x12, 0x34, 0x56, 0x78, 0x50, 0x10, 0x00, 0x01, 0x5f, 0xf8, 0x00, 0x00, 0x61, 0x62, 0x63, 0x64,
|
|
};
|
|
// 192.168.123.1 172.16.243.197 TCP 44 43981 → 4660 [ACK] Seq=1 Ack=1 Win=1 Len=4
|
|
const uint8_t kIp4Packet[] = {0x45, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x9f,
|
|
0x4c, 192, 168, 123, 1, 172, 16, 243, 197, 0xab, 0xcd,
|
|
0x12, 0x34, 0x87, 0x65, 0x43, 0x21, 0x12, 0x34, 0x56, 0x78, 0x50,
|
|
0x10, 0x00, 0x01, 0x1e, 0x54, 0x00, 0x00, 0x61, 0x62, 0x63, 0x64};
|
|
|
|
Verify6To4("Valid v6 TCP", kIp6Packet, kIp4Packet, kErrorNone);
|
|
}
|
|
|
|
{
|
|
// 172.16.243.197 192.168.123.1 TCP 44 43981 → 4660 [ACK] Seq=1 Ack=1 Win=1 Len=4
|
|
const uint8_t kIp4Packet[] = {0x45, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x9f,
|
|
0x4c, 172, 16, 243, 197, 192, 168, 123, 1, 0xab, 0xcd,
|
|
0x12, 0x34, 0x87, 0x65, 0x43, 0x21, 0x12, 0x34, 0x56, 0x78, 0x50,
|
|
0x10, 0x00, 0x01, 0x1e, 0x54, 0x00, 0x00, 0x61, 0x62, 0x63, 0x64};
|
|
// fd01::ac10:f3c5 fd02::1 TCP 64 43981 → 4660 [ACK] Seq=1 Ack=1 Win=1 Len=4
|
|
const uint8_t kIp6Packet[] = {
|
|
0x60, 0x00, 0x00, 0x00, 0x00, 0x18, 0x06, 0x40, 0xfd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 172, 16, 243, 197, 0xfd, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xab, 0xcd, 0x12, 0x34, 0x87, 0x65, 0x43, 0x21,
|
|
0x12, 0x34, 0x56, 0x78, 0x50, 0x10, 0x00, 0x01, 0x5f, 0xf8, 0x00, 0x00, 0x61, 0x62, 0x63, 0x64,
|
|
};
|
|
|
|
Verify4To6("Valid v4 TCP", kIp4Packet, kIp6Packet, kErrorNone);
|
|
}
|
|
|
|
{
|
|
// fd02::1 fd01::ac10:f3c5 ICMPv6 52 Echo (ping) request id=0xaabb, seq=1, hop limit=64
|
|
const uint8_t kIp6Packet[] = {
|
|
0x60, 0x08, 0x6e, 0x38, 0x00, 0x0c, 0x3a, 0x40, 0xfd, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
172, 16, 243, 197, 0x80, 0x00, 0x76, 0x59, 0xaa, 0xbb, 0x00, 0x01, 0x61, 0x62, 0x63, 0x64,
|
|
};
|
|
// 192.168.123.1 172.16.243.197 ICMP 32 Echo (ping) request id=0xaabb, seq=1/256, ttl=63
|
|
const uint8_t kIp4Packet[] = {0x45, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x9f,
|
|
0x5d, 192, 168, 123, 1, 172, 16, 243, 197, 0x08, 0x00,
|
|
0x88, 0x7c, 0xaa, 0xbb, 0x00, 0x01, 0x61, 0x62, 0x63, 0x64};
|
|
|
|
Verify6To4("Valid v6 ICMP ping", kIp6Packet, kIp4Packet, kErrorNone);
|
|
}
|
|
|
|
{
|
|
// 172.16.243.197 192.168.123.1 ICMP 32 Echo (ping) reply id=0xaabb, seq=1/256, ttl=63
|
|
const uint8_t kIp4Packet[] = {0x45, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x01, 0xa0,
|
|
0x5d, 172, 16, 243, 197, 192, 168, 123, 1, 0x00, 0x00,
|
|
0x90, 0x7c, 0xaa, 0xbb, 0x00, 0x01, 0x61, 0x62, 0x63, 0x64};
|
|
// fd01::ac10:f3c5 fd02::1 ICMPv6 52 Echo (ping) reply id=0xaabb, seq=1, hop limit=62
|
|
const uint8_t kIp6Packet[] = {
|
|
0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x3a, 0x3f, 0xfd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 172, 16, 243, 197, 0xfd, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x01, 0x81, 0x00, 0x75, 0x59, 0xaa, 0xbb, 0x00, 0x01, 0x61, 0x62, 0x63, 0x64,
|
|
};
|
|
|
|
Verify4To6("Valid v4 ICMP ping", kIp4Packet, kIp6Packet, kErrorNone);
|
|
}
|
|
|
|
{
|
|
// fd02::1 N/A IPv6 39 Invalid IPv6 header
|
|
const uint8_t kIp6Packet[] = {0x60, 0x08, 0x6e, 0x38, 0x00, 0x0c, 0x11, 0x40, 0xfd, 0x02, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfd, 0x01,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 172, 16, 243};
|
|
|
|
Verify6To4("Invalid v6", kIp6Packet, kErrorDrop);
|
|
}
|
|
|
|
{
|
|
// 172.16.243.197 N/A IPv4 19 [Malformed Packet]
|
|
const uint8_t kIp4Packet[] = {0x45, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x11,
|
|
0xa0, 0x4c, 172, 16, 243, 197, 192, 168, 123};
|
|
|
|
Verify4To6("Invalid v4", kIp4Packet, kErrorDrop);
|
|
}
|
|
|
|
{
|
|
// 172.16.243.197 192.168.123.2 UDP 32 43981 → 4660 Len=4
|
|
const uint8_t kIp4Packet[] = {0x45, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x11, 0xa0,
|
|
0x4c, 172, 16, 243, 197, 192, 168, 123, 2, 0xab, 0xcd,
|
|
0x12, 0x34, 0x00, 0x0c, 0xa1, 0x8c, 0x61, 0x62, 0x63, 0x64};
|
|
|
|
Verify4To6("No v4 mapping", kIp4Packet, kErrorDrop);
|
|
}
|
|
|
|
Log("End of TestNat64Translation");
|
|
|
|
testFreeInstance(sInstance);
|
|
}
|
|
|
|
void TestNat64Counters(void)
|
|
{
|
|
Ip6::Prefix prefix;
|
|
Ip4::Cidr cidr;
|
|
Translator::AddressMappingIterator iter;
|
|
Translator::AddressMapping mapping;
|
|
Translator::ProtocolCounters expectedCounters;
|
|
|
|
Log("--------------------------------------------------------------------------------------------");
|
|
Log("TestNat64Counters");
|
|
|
|
sInstance = testInitInstance();
|
|
VerifyOrQuit(sInstance != nullptr);
|
|
|
|
SuccessOrQuit(prefix.FromString("fd01::/96"));
|
|
SuccessOrQuit(cidr.FromString("192.168.123.1/32"));
|
|
|
|
SuccessOrQuit(sInstance->Get<Translator>().SetIp4Cidr(cidr));
|
|
sInstance->Get<Translator>().SetNat64Prefix(prefix);
|
|
sInstance->Get<Translator>().SetEnabled(true);
|
|
|
|
// Step 1: Make the mapping table dirty.
|
|
{
|
|
// fd02::1 fd01::ac10:f3c5 UDP 52 43981 → 4660 Len=4
|
|
const uint8_t kIp6Packet[] = {
|
|
0x60, 0x08, 0x6e, 0x38, 0x00, 0x0c, 0x11, 0x40, 0xfd, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
172, 16, 243, 197, 0xab, 0xcd, 0x12, 0x34, 0x00, 0x0c, 0xe3, 0x31, 0x61, 0x62, 0x63, 0x64,
|
|
};
|
|
// 192.168.123.1 172.16.243.197 UDP 32 43981 → 4660 Len=4
|
|
const uint8_t kIp4Packet[] = {0x45, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0x9f,
|
|
0x4d, 192, 168, 123, 1, 172, 16, 243, 197, 0xab, 0xcd,
|
|
0x12, 0x34, 0x00, 0x0c, 0xa1, 0x8d, 0x61, 0x62, 0x63, 0x64};
|
|
|
|
Verify6To4("First translation", kIp6Packet, kIp4Packet, kErrorNone);
|
|
}
|
|
|
|
iter.Init(*sInstance);
|
|
|
|
SuccessOrQuit(iter.GetNext(mapping));
|
|
|
|
expectedCounters.Clear();
|
|
expectedCounters.mUdp.m6To4Packets = 1;
|
|
expectedCounters.mUdp.m6To4Bytes = 12;
|
|
expectedCounters.mTotal.m6To4Packets = 1;
|
|
expectedCounters.mTotal.m6To4Bytes = 12;
|
|
VerifyOrQuit(AsCoreType(&mapping.mCounters) == expectedCounters);
|
|
|
|
VerifyOrQuit(iter.GetNext(mapping) == kErrorNotFound);
|
|
|
|
// Step 2: Release the mapping table item.
|
|
{
|
|
SuccessOrQuit(prefix.FromString("fd01::/96"));
|
|
SuccessOrQuit(cidr.FromString("192.168.124.1/32"));
|
|
|
|
SuccessOrQuit(sInstance->Get<Translator>().SetIp4Cidr(cidr));
|
|
sInstance->Get<Translator>().SetNat64Prefix(prefix);
|
|
}
|
|
|
|
// Step 3: Reuse the same object for new mapping table item.
|
|
// If the counters are not reset, the verification below will fail.
|
|
{
|
|
// fd02::1 fd01::ac10:f3c5 UDP 52 43981 → 4660 Len=4
|
|
const uint8_t kIp6Packet[] = {
|
|
0x60, 0x08, 0x6e, 0x38, 0x00, 0x0c, 0x11, 0x40, 0xfd, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
172, 16, 243, 197, 0xab, 0xcd, 0x12, 0x34, 0x00, 0x0c, 0xe3, 0x31, 0x61, 0x62, 0x63, 0x64,
|
|
};
|
|
// 192.168.124.1 172.16.243.197 UDP 32 43981 → 4660 Len=4
|
|
const uint8_t kIp4Packet[] = {0x45, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0x9e,
|
|
0x4d, 192, 168, 124, 1, 172, 16, 243, 197, 0xab, 0xcd,
|
|
0x12, 0x34, 0x00, 0x0c, 0xa0, 0x8d, 0x61, 0x62, 0x63, 0x64};
|
|
|
|
Verify6To4("Translation with new mapping", kIp6Packet, kIp4Packet, kErrorNone);
|
|
}
|
|
|
|
iter.Init(*sInstance);
|
|
|
|
SuccessOrQuit(iter.GetNext(mapping));
|
|
|
|
expectedCounters.Clear();
|
|
expectedCounters.mUdp.m6To4Packets = 1;
|
|
expectedCounters.mUdp.m6To4Bytes = 12;
|
|
expectedCounters.mTotal.m6To4Packets = 1;
|
|
expectedCounters.mTotal.m6To4Bytes = 12;
|
|
VerifyOrQuit(AsCoreType(&mapping.mCounters) == expectedCounters);
|
|
|
|
VerifyOrQuit(iter.GetNext(mapping) == kErrorNotFound);
|
|
|
|
Log("End of TestNat64Counters");
|
|
}
|
|
|
|
} // namespace Nat64
|
|
} // namespace ot
|
|
|
|
#endif // OPENTHREAD_CONFIG_NAT64_TRANSLATOR_ENABLE
|
|
|
|
int main(void)
|
|
{
|
|
#if OPENTHREAD_CONFIG_NAT64_TRANSLATOR_ENABLE
|
|
ot::Nat64::TestNat64Translation();
|
|
ot::Nat64::TestNat64Counters();
|
|
printf("All tests passed\n");
|
|
#else
|
|
printf("NAT64 is not enabled\n");
|
|
#endif
|
|
|
|
return 0;
|
|
}
|