mirror of
https://github.com/espressif/openthread.git
synced 2026-08-04 09:57:47 +00:00
This change replaces the `Translator::Result` enum with the standard `Error` type to report the outcome of a translation attempt. This simplifies the implementation and aligns it with the rest of the codebase. The mapping from the old `Result` to the new `Error` is as follows: - `kForward` is replaced by `kErrorNone` - `kDrop` is replaced by `kErrorDrop` - `kNotTranslated` is replaced by `kErrorAbort` The `kErrorAbort` return value signals to the caller that no translation was performed, and it can proceed with normal processing of the message. Additionally, the translation methods are renamed for better clarity.
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(0);
|
|
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(0);
|
|
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;
|
|
}
|