From b72d7144ee40e0550d6f507dff4be7a6b79c6100 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Wed, 3 Jun 2026 19:19:25 -0700 Subject: [PATCH] [cli] refactor IPv6 address parsing and synthesis helper (#13205) This commit renames the static helper `Utils::ParseToIp6Address()` to `Utils::ParseOrSynthesizeIp6Address()` to better reflect its behavior of parsing an IPv6 address or synthesizing one from an IPv4 address via NAT64. Additionally, the method is refactored into a non-static member of the `Utils` class. This eliminates the need to manually pass the `otInstance` pointer, as the `Utils` class already maintains it. The internal implementation is also simplified to reduce nesting by exiting early upon successful IPv6 address parsing. All callers in the CLI module (TCP, UDP, Ping, DNS) have been updated to use the new member method. --- src/cli/cli_dns.cpp | 3 ++- src/cli/cli_ping.cpp | 2 +- src/cli/cli_tcp.cpp | 2 +- src/cli/cli_udp.cpp | 4 ++-- src/cli/cli_utils.cpp | 28 +++++++++++++++------------- src/cli/cli_utils.hpp | 12 ++++-------- 6 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/cli/cli_dns.cpp b/src/cli/cli_dns.cpp index 2aa0f15d8..8c843bc85 100644 --- a/src/cli/cli_dns.cpp +++ b/src/cli/cli_dns.cpp @@ -452,7 +452,8 @@ otError Dns::GetDnsConfig(Arg aArgs[], otDnsQueryConfig *&aConfig) VerifyOrExit(!aArgs[0].IsEmpty(), aConfig = nullptr); - SuccessOrExit(error = ParseToIp6Address(GetInstancePtr(), aArgs[0], aConfig->mServerSockAddr.mAddress, nat64Synth)); + SuccessOrExit(error = ParseOrSynthesizeIp6Address(aArgs[0], aConfig->mServerSockAddr.mAddress, nat64Synth)); + if (nat64Synth) { OutputFormat("Synthesized IPv6 DNS server address: "); diff --git a/src/cli/cli_ping.cpp b/src/cli/cli_ping.cpp index 2100ea2a7..af243f62b 100644 --- a/src/cli/cli_ping.cpp +++ b/src/cli/cli_ping.cpp @@ -96,7 +96,7 @@ otError PingSender::Process(Arg aArgs[]) aArgs++; } - SuccessOrExit(error = ParseToIp6Address(GetInstancePtr(), aArgs[0], config.mDestination, nat64Synth)); + SuccessOrExit(error = ParseOrSynthesizeIp6Address(aArgs[0], config.mDestination, nat64Synth)); if (nat64Synth) { diff --git a/src/cli/cli_tcp.cpp b/src/cli/cli_tcp.cpp index 96275ab69..7c5dadba6 100644 --- a/src/cli/cli_tcp.cpp +++ b/src/cli/cli_tcp.cpp @@ -400,7 +400,7 @@ template <> otError TcpExample::Process(Arg aArgs[]) VerifyOrExit(mInitialized, error = OT_ERROR_INVALID_STATE); - SuccessOrExit(error = ParseToIp6Address(GetInstancePtr(), aArgs[0], sockaddr.mAddress, nat64Synth)); + SuccessOrExit(error = ParseOrSynthesizeIp6Address(aArgs[0], sockaddr.mAddress, nat64Synth)); if (nat64Synth) { diff --git a/src/cli/cli_udp.cpp b/src/cli/cli_udp.cpp index b59dd67c4..50f17cef0 100644 --- a/src/cli/cli_udp.cpp +++ b/src/cli/cli_udp.cpp @@ -144,7 +144,7 @@ template <> otError UdpExample::Process(Arg aArgs[]) otSockAddr sockaddr; bool nat64Synth; - SuccessOrExit(error = ParseToIp6Address(GetInstancePtr(), aArgs[0], sockaddr.mAddress, nat64Synth)); + SuccessOrExit(error = ParseOrSynthesizeIp6Address(aArgs[0], sockaddr.mAddress, nat64Synth)); if (nat64Synth) { @@ -281,7 +281,7 @@ template <> otError UdpExample::Process(Arg aArgs[]) { bool nat64Synth; - SuccessOrExit(error = ParseToIp6Address(GetInstancePtr(), aArgs[0], messageInfo.mPeerAddr, nat64Synth)); + SuccessOrExit(error = ParseOrSynthesizeIp6Address(aArgs[0], messageInfo.mPeerAddr, nat64Synth)); if (nat64Synth) { diff --git a/src/cli/cli_utils.cpp b/src/cli/cli_utils.cpp index 6709e0163..be7d94767 100644 --- a/src/cli/cli_utils.cpp +++ b/src/cli/cli_utils.cpp @@ -629,25 +629,27 @@ const char *Utils::PreferenceToString(signed int aPreference) } #if OPENTHREAD_FTD || OPENTHREAD_MTD -otError Utils::ParseToIp6Address(otInstance *aInstance, const Arg &aArg, otIp6Address &aAddress, bool &aSynthesized) -{ - Error error = OT_ERROR_NONE; - VerifyOrExit(!aArg.IsEmpty(), error = OT_ERROR_INVALID_ARGS); - error = aArg.ParseAsIp6Address(aAddress); +otError Utils::ParseOrSynthesizeIp6Address(const Arg &aArg, otIp6Address &aAddress, bool &aSynthesized) +{ + Error error; + otIp4Address ip4Address; + aSynthesized = false; - if (error != OT_ERROR_NONE) - { - // It might be an IPv4 address, let's have a try. - otIp4Address ip4Address; + error = aArg.ParseAsIp6Address(aAddress); - // Do not touch the error value if we failed to parse it as an IPv4 address. - SuccessOrExit(aArg.ParseAsIp4Address(ip4Address)); - SuccessOrExit(error = otNat64SynthesizeIp6Address(aInstance, &ip4Address, &aAddress)); - aSynthesized = true; + if (error == OT_ERROR_NONE) + { + ExitNow(); } + // Try to parse it as an IPv4 address and synthesize. + + SuccessOrExit(error = aArg.ParseAsIp4Address(ip4Address)); + SuccessOrExit(error = otNat64SynthesizeIp6Address(GetInstancePtr(), &ip4Address, &aAddress)); + aSynthesized = true; + exit: return error; } diff --git a/src/cli/cli_utils.hpp b/src/cli/cli_utils.hpp index 6ad136c30..a7acb074b 100644 --- a/src/cli/cli_utils.hpp +++ b/src/cli/cli_utils.hpp @@ -674,24 +674,20 @@ public: static const char *PreferenceToString(signed int aPreference); /** - * Parses the argument as an IP address. + * Parses the argument as an IPv6 address or synthesizes it from an IPv4 address. * * If the argument string is an IPv4 address, this method will try to synthesize an IPv6 address using preferred * NAT64 prefix in the network data. * - * @param[in] aInstance A pointer to OpenThread instance. * @param[in] aArg The argument string to parse. - * @param[out] aAddress A reference to an `otIp6Address` to output the parsed IPv6 address. + * @param[out] aAddress A reference to an `otIp6Address` to output the parsed/synthesized IPv6 address. * @param[out] aSynthesized Whether @p aAddress is synthesized from an IPv4 address. * - * @retval OT_ERROR_NONE The argument was parsed successfully. + * @retval OT_ERROR_NONE The argument was parsed/synthesized successfully. * @retval OT_ERROR_INVALID_ARGS The argument is empty or does not contain a valid IP address. * @retval OT_ERROR_INVALID_STATE No valid NAT64 prefix in the network data. */ - static otError ParseToIp6Address(otInstance *aInstance, - const Arg &aArg, - otIp6Address &aAddress, - bool &aSynthesized); + otError ParseOrSynthesizeIp6Address(const Arg &aArg, otIp6Address &aAddress, bool &aSynthesized); /** * Parses the argument as a Joiner Discerner.