xref: /aosp_15_r20/external/openthread/src/cli/cli_dns.cpp (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1*cfb92d14SAndroid Build Coastguard Worker /*
2*cfb92d14SAndroid Build Coastguard Worker  *  Copyright (c) 2023, The OpenThread Authors.
3*cfb92d14SAndroid Build Coastguard Worker  *  All rights reserved.
4*cfb92d14SAndroid Build Coastguard Worker  *
5*cfb92d14SAndroid Build Coastguard Worker  *  Redistribution and use in source and binary forms, with or without
6*cfb92d14SAndroid Build Coastguard Worker  *  modification, are permitted provided that the following conditions are met:
7*cfb92d14SAndroid Build Coastguard Worker  *  1. Redistributions of source code must retain the above copyright
8*cfb92d14SAndroid Build Coastguard Worker  *     notice, this list of conditions and the following disclaimer.
9*cfb92d14SAndroid Build Coastguard Worker  *  2. Redistributions in binary form must reproduce the above copyright
10*cfb92d14SAndroid Build Coastguard Worker  *     notice, this list of conditions and the following disclaimer in the
11*cfb92d14SAndroid Build Coastguard Worker  *     documentation and/or other materials provided with the distribution.
12*cfb92d14SAndroid Build Coastguard Worker  *  3. Neither the name of the copyright holder nor the
13*cfb92d14SAndroid Build Coastguard Worker  *     names of its contributors may be used to endorse or promote products
14*cfb92d14SAndroid Build Coastguard Worker  *     derived from this software without specific prior written permission.
15*cfb92d14SAndroid Build Coastguard Worker  *
16*cfb92d14SAndroid Build Coastguard Worker  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*cfb92d14SAndroid Build Coastguard Worker  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*cfb92d14SAndroid Build Coastguard Worker  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*cfb92d14SAndroid Build Coastguard Worker  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*cfb92d14SAndroid Build Coastguard Worker  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*cfb92d14SAndroid Build Coastguard Worker  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*cfb92d14SAndroid Build Coastguard Worker  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*cfb92d14SAndroid Build Coastguard Worker  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*cfb92d14SAndroid Build Coastguard Worker  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*cfb92d14SAndroid Build Coastguard Worker  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*cfb92d14SAndroid Build Coastguard Worker  *  POSSIBILITY OF SUCH DAMAGE.
27*cfb92d14SAndroid Build Coastguard Worker  */
28*cfb92d14SAndroid Build Coastguard Worker 
29*cfb92d14SAndroid Build Coastguard Worker /**
30*cfb92d14SAndroid Build Coastguard Worker  * @file
31*cfb92d14SAndroid Build Coastguard Worker  *   This file implements CLI for DNS (client and server/resolver).
32*cfb92d14SAndroid Build Coastguard Worker  */
33*cfb92d14SAndroid Build Coastguard Worker 
34*cfb92d14SAndroid Build Coastguard Worker #include "cli_dns.hpp"
35*cfb92d14SAndroid Build Coastguard Worker 
36*cfb92d14SAndroid Build Coastguard Worker #include "cli/cli.hpp"
37*cfb92d14SAndroid Build Coastguard Worker 
38*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CLI_DNS_ENABLE
39*cfb92d14SAndroid Build Coastguard Worker 
40*cfb92d14SAndroid Build Coastguard Worker namespace ot {
41*cfb92d14SAndroid Build Coastguard Worker namespace Cli {
42*cfb92d14SAndroid Build Coastguard Worker 
43*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
44*cfb92d14SAndroid Build Coastguard Worker 
Process(Arg aArgs[])45*cfb92d14SAndroid Build Coastguard Worker template <> otError Dns::Process<Cmd("compression")>(Arg aArgs[])
46*cfb92d14SAndroid Build Coastguard Worker {
47*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
48*cfb92d14SAndroid Build Coastguard Worker 
49*cfb92d14SAndroid Build Coastguard Worker     /**
50*cfb92d14SAndroid Build Coastguard Worker      * @cli dns compression
51*cfb92d14SAndroid Build Coastguard Worker      * @code
52*cfb92d14SAndroid Build Coastguard Worker      * dns compression
53*cfb92d14SAndroid Build Coastguard Worker      * Enabled
54*cfb92d14SAndroid Build Coastguard Worker      * @endcode
55*cfb92d14SAndroid Build Coastguard Worker      * @cparam dns compression [@ca{enable|disable}]
56*cfb92d14SAndroid Build Coastguard Worker      * @par api_copy
57*cfb92d14SAndroid Build Coastguard Worker      * #otDnsIsNameCompressionEnabled
58*cfb92d14SAndroid Build Coastguard Worker      * @par
59*cfb92d14SAndroid Build Coastguard Worker      * By default DNS name compression is enabled. When disabled,
60*cfb92d14SAndroid Build Coastguard Worker      * DNS names are appended as full and never compressed. This
61*cfb92d14SAndroid Build Coastguard Worker      * is applicable to OpenThread's DNS and SRP client/server
62*cfb92d14SAndroid Build Coastguard Worker      * modules."
63*cfb92d14SAndroid Build Coastguard Worker      * `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is required.
64*cfb92d14SAndroid Build Coastguard Worker      */
65*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0].IsEmpty())
66*cfb92d14SAndroid Build Coastguard Worker     {
67*cfb92d14SAndroid Build Coastguard Worker         OutputEnabledDisabledStatus(otDnsIsNameCompressionEnabled());
68*cfb92d14SAndroid Build Coastguard Worker     }
69*cfb92d14SAndroid Build Coastguard Worker     /**
70*cfb92d14SAndroid Build Coastguard Worker      * @cli dns compression (enable,disable)
71*cfb92d14SAndroid Build Coastguard Worker      * @code
72*cfb92d14SAndroid Build Coastguard Worker      * dns compression enable
73*cfb92d14SAndroid Build Coastguard Worker      * Enabled
74*cfb92d14SAndroid Build Coastguard Worker      * @endcode
75*cfb92d14SAndroid Build Coastguard Worker      * @code
76*cfb92d14SAndroid Build Coastguard Worker      * dns compression disable
77*cfb92d14SAndroid Build Coastguard Worker      * Done
78*cfb92d14SAndroid Build Coastguard Worker      * dns compression
79*cfb92d14SAndroid Build Coastguard Worker      * Disabled
80*cfb92d14SAndroid Build Coastguard Worker      * Done
81*cfb92d14SAndroid Build Coastguard Worker      * @endcode
82*cfb92d14SAndroid Build Coastguard Worker      * @cparam dns compression [@ca{enable|disable}]
83*cfb92d14SAndroid Build Coastguard Worker      * @par
84*cfb92d14SAndroid Build Coastguard Worker      * Set the "DNS name compression" mode.
85*cfb92d14SAndroid Build Coastguard Worker      * @par
86*cfb92d14SAndroid Build Coastguard Worker      * By default DNS name compression is enabled. When disabled,
87*cfb92d14SAndroid Build Coastguard Worker      * DNS names are appended as full and never compressed. This
88*cfb92d14SAndroid Build Coastguard Worker      * is applicable to OpenThread's DNS and SRP client/server
89*cfb92d14SAndroid Build Coastguard Worker      * modules."
90*cfb92d14SAndroid Build Coastguard Worker      * `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is required.
91*cfb92d14SAndroid Build Coastguard Worker      * @sa otDnsSetNameCompressionEnabled
92*cfb92d14SAndroid Build Coastguard Worker      */
93*cfb92d14SAndroid Build Coastguard Worker     else
94*cfb92d14SAndroid Build Coastguard Worker     {
95*cfb92d14SAndroid Build Coastguard Worker         bool enable;
96*cfb92d14SAndroid Build Coastguard Worker 
97*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = ParseEnableOrDisable(aArgs[0], enable));
98*cfb92d14SAndroid Build Coastguard Worker         otDnsSetNameCompressionEnabled(enable);
99*cfb92d14SAndroid Build Coastguard Worker     }
100*cfb92d14SAndroid Build Coastguard Worker 
101*cfb92d14SAndroid Build Coastguard Worker exit:
102*cfb92d14SAndroid Build Coastguard Worker     return error;
103*cfb92d14SAndroid Build Coastguard Worker }
104*cfb92d14SAndroid Build Coastguard Worker 
105*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
106*cfb92d14SAndroid Build Coastguard Worker 
107*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
108*cfb92d14SAndroid Build Coastguard Worker 
Process(Arg aArgs[])109*cfb92d14SAndroid Build Coastguard Worker template <> otError Dns::Process<Cmd("config")>(Arg aArgs[])
110*cfb92d14SAndroid Build Coastguard Worker {
111*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
112*cfb92d14SAndroid Build Coastguard Worker 
113*cfb92d14SAndroid Build Coastguard Worker     /**
114*cfb92d14SAndroid Build Coastguard Worker      * @cli dns config
115*cfb92d14SAndroid Build Coastguard Worker      * @code
116*cfb92d14SAndroid Build Coastguard Worker      * dns config
117*cfb92d14SAndroid Build Coastguard Worker      * Server: [fd00:0:0:0:0:0:0:1]:1234
118*cfb92d14SAndroid Build Coastguard Worker      * ResponseTimeout: 5000 ms
119*cfb92d14SAndroid Build Coastguard Worker      * MaxTxAttempts: 2
120*cfb92d14SAndroid Build Coastguard Worker      * RecursionDesired: no
121*cfb92d14SAndroid Build Coastguard Worker      * ServiceMode: srv
122*cfb92d14SAndroid Build Coastguard Worker      * Nat64Mode: allow
123*cfb92d14SAndroid Build Coastguard Worker      * Done
124*cfb92d14SAndroid Build Coastguard Worker      * @endcode
125*cfb92d14SAndroid Build Coastguard Worker      * @par api_copy
126*cfb92d14SAndroid Build Coastguard Worker      * #otDnsClientGetDefaultConfig
127*cfb92d14SAndroid Build Coastguard Worker      * @par
128*cfb92d14SAndroid Build Coastguard Worker      * The config includes the server IPv6 address and port, response
129*cfb92d14SAndroid Build Coastguard Worker      * timeout in msec (wait time to rx response), maximum tx attempts
130*cfb92d14SAndroid Build Coastguard Worker      * before reporting failure, boolean flag to indicate whether the server
131*cfb92d14SAndroid Build Coastguard Worker      * can resolve the query recursively or not.
132*cfb92d14SAndroid Build Coastguard Worker      * `OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE` is required.
133*cfb92d14SAndroid Build Coastguard Worker      */
134*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0].IsEmpty())
135*cfb92d14SAndroid Build Coastguard Worker     {
136*cfb92d14SAndroid Build Coastguard Worker         const otDnsQueryConfig *defaultConfig = otDnsClientGetDefaultConfig(GetInstancePtr());
137*cfb92d14SAndroid Build Coastguard Worker 
138*cfb92d14SAndroid Build Coastguard Worker         OutputFormat("Server: ");
139*cfb92d14SAndroid Build Coastguard Worker         OutputSockAddrLine(defaultConfig->mServerSockAddr);
140*cfb92d14SAndroid Build Coastguard Worker         OutputLine("ResponseTimeout: %lu ms", ToUlong(defaultConfig->mResponseTimeout));
141*cfb92d14SAndroid Build Coastguard Worker         OutputLine("MaxTxAttempts: %u", defaultConfig->mMaxTxAttempts);
142*cfb92d14SAndroid Build Coastguard Worker         OutputLine("RecursionDesired: %s",
143*cfb92d14SAndroid Build Coastguard Worker                    (defaultConfig->mRecursionFlag == OT_DNS_FLAG_RECURSION_DESIRED) ? "yes" : "no");
144*cfb92d14SAndroid Build Coastguard Worker         OutputLine("ServiceMode: %s", DnsConfigServiceModeToString(defaultConfig->mServiceMode));
145*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
146*cfb92d14SAndroid Build Coastguard Worker         OutputLine("Nat64Mode: %s", (defaultConfig->mNat64Mode == OT_DNS_NAT64_ALLOW) ? "allow" : "disallow");
147*cfb92d14SAndroid Build Coastguard Worker #endif
148*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_DNS_CLIENT_OVER_TCP_ENABLE
149*cfb92d14SAndroid Build Coastguard Worker         OutputLine("TransportProtocol: %s", (defaultConfig->mTransportProto == OT_DNS_TRANSPORT_UDP) ? "udp" : "tcp");
150*cfb92d14SAndroid Build Coastguard Worker #endif
151*cfb92d14SAndroid Build Coastguard Worker     }
152*cfb92d14SAndroid Build Coastguard Worker     /**
153*cfb92d14SAndroid Build Coastguard Worker      * @cli dns config (set)
154*cfb92d14SAndroid Build Coastguard Worker      * @code
155*cfb92d14SAndroid Build Coastguard Worker      * dns config fd00::1 1234 5000 2 0
156*cfb92d14SAndroid Build Coastguard Worker      * Done
157*cfb92d14SAndroid Build Coastguard Worker      * @endcode
158*cfb92d14SAndroid Build Coastguard Worker      * @code
159*cfb92d14SAndroid Build Coastguard Worker      * dns config
160*cfb92d14SAndroid Build Coastguard Worker      * Server: [fd00:0:0:0:0:0:0:1]:1234
161*cfb92d14SAndroid Build Coastguard Worker      * ResponseTimeout: 5000 ms
162*cfb92d14SAndroid Build Coastguard Worker      * MaxTxAttempts: 2
163*cfb92d14SAndroid Build Coastguard Worker      * RecursionDesired: no
164*cfb92d14SAndroid Build Coastguard Worker      * ServiceMode: srv_txt_opt
165*cfb92d14SAndroid Build Coastguard Worker      * Nat64Mode: allow
166*cfb92d14SAndroid Build Coastguard Worker      * TransportProtocol: udp
167*cfb92d14SAndroid Build Coastguard Worker      * Done
168*cfb92d14SAndroid Build Coastguard Worker      * @endcode
169*cfb92d14SAndroid Build Coastguard Worker      * @code
170*cfb92d14SAndroid Build Coastguard Worker      * dns config fd00::2
171*cfb92d14SAndroid Build Coastguard Worker      * Done
172*cfb92d14SAndroid Build Coastguard Worker      * @endcode
173*cfb92d14SAndroid Build Coastguard Worker      * @code
174*cfb92d14SAndroid Build Coastguard Worker      * dns config
175*cfb92d14SAndroid Build Coastguard Worker      * Server: [fd00:0:0:0:0:0:0:2]:53
176*cfb92d14SAndroid Build Coastguard Worker      * ResponseTimeout: 6000 ms
177*cfb92d14SAndroid Build Coastguard Worker      * MaxTxAttempts: 3
178*cfb92d14SAndroid Build Coastguard Worker      * RecursionDesired: yes
179*cfb92d14SAndroid Build Coastguard Worker      * ServiceMode: srv_txt_opt
180*cfb92d14SAndroid Build Coastguard Worker      * Nat64Mode: allow
181*cfb92d14SAndroid Build Coastguard Worker      * TransportProtocol: udp
182*cfb92d14SAndroid Build Coastguard Worker      * Done
183*cfb92d14SAndroid Build Coastguard Worker      * @endcode
184*cfb92d14SAndroid Build Coastguard Worker      * @par api_copy
185*cfb92d14SAndroid Build Coastguard Worker      * #otDnsClientSetDefaultConfig
186*cfb92d14SAndroid Build Coastguard Worker      * @cparam dns config [@ca{dns-server-IP}] [@ca{dns-server-port}] <!--
187*cfb92d14SAndroid Build Coastguard Worker      * -->                [@ca{response-timeout-ms}] [@ca{max-tx-attempts}] <!--
188*cfb92d14SAndroid Build Coastguard Worker      * -->                [@ca{recursion-desired-boolean}] [@ca{service-mode}] <!--
189*cfb92d14SAndroid Build Coastguard Worker      * -->                [@ca{protocol}]
190*cfb92d14SAndroid Build Coastguard Worker      * @par
191*cfb92d14SAndroid Build Coastguard Worker      * We can leave some of the fields as unspecified (or use value zero). The
192*cfb92d14SAndroid Build Coastguard Worker      * unspecified fields are replaced by the corresponding OT config option
193*cfb92d14SAndroid Build Coastguard Worker      * definitions `OPENTHREAD_CONFIG_DNS_CLIENT_DEFAULT` to form the default
194*cfb92d14SAndroid Build Coastguard Worker      * query config.
195*cfb92d14SAndroid Build Coastguard Worker      * `OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE` is required.
196*cfb92d14SAndroid Build Coastguard Worker      */
197*cfb92d14SAndroid Build Coastguard Worker     else
198*cfb92d14SAndroid Build Coastguard Worker     {
199*cfb92d14SAndroid Build Coastguard Worker         otDnsQueryConfig  queryConfig;
200*cfb92d14SAndroid Build Coastguard Worker         otDnsQueryConfig *config = &queryConfig;
201*cfb92d14SAndroid Build Coastguard Worker 
202*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = GetDnsConfig(aArgs, config));
203*cfb92d14SAndroid Build Coastguard Worker         otDnsClientSetDefaultConfig(GetInstancePtr(), config);
204*cfb92d14SAndroid Build Coastguard Worker     }
205*cfb92d14SAndroid Build Coastguard Worker 
206*cfb92d14SAndroid Build Coastguard Worker exit:
207*cfb92d14SAndroid Build Coastguard Worker     return error;
208*cfb92d14SAndroid Build Coastguard Worker }
209*cfb92d14SAndroid Build Coastguard Worker 
210*cfb92d14SAndroid Build Coastguard Worker /**
211*cfb92d14SAndroid Build Coastguard Worker  * @cli dns resolve
212*cfb92d14SAndroid Build Coastguard Worker  * @code
213*cfb92d14SAndroid Build Coastguard Worker  * dns resolve ipv6.google.com
214*cfb92d14SAndroid Build Coastguard Worker  * DNS response for ipv6.google.com - 2a00:1450:401b:801:0:0:0:200e TTL: 300
215*cfb92d14SAndroid Build Coastguard Worker  * @endcode
216*cfb92d14SAndroid Build Coastguard Worker  * @code
217*cfb92d14SAndroid Build Coastguard Worker  * dns resolve example.com 8.8.8.8
218*cfb92d14SAndroid Build Coastguard Worker  * Synthesized IPv6 DNS server address: fdde:ad00:beef:2:0:0:808:808
219*cfb92d14SAndroid Build Coastguard Worker  * DNS response for example.com. - fd4c:9574:3720:2:0:0:5db8:d822 TTL:20456
220*cfb92d14SAndroid Build Coastguard Worker  * Done
221*cfb92d14SAndroid Build Coastguard Worker  * @endcode
222*cfb92d14SAndroid Build Coastguard Worker  * @cparam dns resolve @ca{hostname} [@ca{dns-server-IP}] <!--
223*cfb92d14SAndroid Build Coastguard Worker  * -->                 [@ca{dns-server-port}] [@ca{response-timeout-ms}] <!--
224*cfb92d14SAndroid Build Coastguard Worker  * -->                 [@ca{max-tx-attempts}] [@ca{recursion-desired-boolean}]
225*cfb92d14SAndroid Build Coastguard Worker  * @par api_copy
226*cfb92d14SAndroid Build Coastguard Worker  * #otDnsClientResolveAddress
227*cfb92d14SAndroid Build Coastguard Worker  * @par
228*cfb92d14SAndroid Build Coastguard Worker  * Send DNS Query to obtain IPv6 address for given hostname.
229*cfb92d14SAndroid Build Coastguard Worker  * @par
230*cfb92d14SAndroid Build Coastguard Worker  * The parameters after hostname are optional. Any unspecified (or zero) value
231*cfb92d14SAndroid Build Coastguard Worker  * for these optional parameters is replaced by the value from the current default
232*cfb92d14SAndroid Build Coastguard Worker  * config (dns config).
233*cfb92d14SAndroid Build Coastguard Worker  * @par
234*cfb92d14SAndroid Build Coastguard Worker  * The DNS server IP can be an IPv4 address, which will be synthesized to an
235*cfb92d14SAndroid Build Coastguard Worker  * IPv6 address using the preferred NAT64 prefix from the network data.
236*cfb92d14SAndroid Build Coastguard Worker  * @par
237*cfb92d14SAndroid Build Coastguard Worker  * Note: The command will return InvalidState when the DNS server IP is an IPv4
238*cfb92d14SAndroid Build Coastguard Worker  * address but the preferred NAT64 prefix is unavailable.
239*cfb92d14SAndroid Build Coastguard Worker  * `OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE` is required.
240*cfb92d14SAndroid Build Coastguard Worker  */
Process(Arg aArgs[])241*cfb92d14SAndroid Build Coastguard Worker template <> otError Dns::Process<Cmd("resolve")>(Arg aArgs[])
242*cfb92d14SAndroid Build Coastguard Worker {
243*cfb92d14SAndroid Build Coastguard Worker     otError           error = OT_ERROR_NONE;
244*cfb92d14SAndroid Build Coastguard Worker     otDnsQueryConfig  queryConfig;
245*cfb92d14SAndroid Build Coastguard Worker     otDnsQueryConfig *config = &queryConfig;
246*cfb92d14SAndroid Build Coastguard Worker 
247*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(!aArgs[0].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
248*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = GetDnsConfig(aArgs + 1, config));
249*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = otDnsClientResolveAddress(GetInstancePtr(), aArgs[0].GetCString(), &HandleDnsAddressResponse,
250*cfb92d14SAndroid Build Coastguard Worker                                                     this, config));
251*cfb92d14SAndroid Build Coastguard Worker     error = OT_ERROR_PENDING;
252*cfb92d14SAndroid Build Coastguard Worker 
253*cfb92d14SAndroid Build Coastguard Worker exit:
254*cfb92d14SAndroid Build Coastguard Worker     return error;
255*cfb92d14SAndroid Build Coastguard Worker }
256*cfb92d14SAndroid Build Coastguard Worker 
257*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
Process(Arg aArgs[])258*cfb92d14SAndroid Build Coastguard Worker template <> otError Dns::Process<Cmd("resolve4")>(Arg aArgs[])
259*cfb92d14SAndroid Build Coastguard Worker {
260*cfb92d14SAndroid Build Coastguard Worker     otError           error = OT_ERROR_NONE;
261*cfb92d14SAndroid Build Coastguard Worker     otDnsQueryConfig  queryConfig;
262*cfb92d14SAndroid Build Coastguard Worker     otDnsQueryConfig *config = &queryConfig;
263*cfb92d14SAndroid Build Coastguard Worker 
264*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(!aArgs[0].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
265*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = GetDnsConfig(aArgs + 1, config));
266*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = otDnsClientResolveIp4Address(GetInstancePtr(), aArgs[0].GetCString(),
267*cfb92d14SAndroid Build Coastguard Worker                                                        &HandleDnsAddressResponse, this, config));
268*cfb92d14SAndroid Build Coastguard Worker     error = OT_ERROR_PENDING;
269*cfb92d14SAndroid Build Coastguard Worker 
270*cfb92d14SAndroid Build Coastguard Worker exit:
271*cfb92d14SAndroid Build Coastguard Worker     return error;
272*cfb92d14SAndroid Build Coastguard Worker }
273*cfb92d14SAndroid Build Coastguard Worker #endif
274*cfb92d14SAndroid Build Coastguard Worker 
275*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
276*cfb92d14SAndroid Build Coastguard Worker 
277*cfb92d14SAndroid Build Coastguard Worker /**
278*cfb92d14SAndroid Build Coastguard Worker  * @cli dns browse
279*cfb92d14SAndroid Build Coastguard Worker  * @code
280*cfb92d14SAndroid Build Coastguard Worker  * dns browse _service._udp.example.com
281*cfb92d14SAndroid Build Coastguard Worker  * DNS browse response for _service._udp.example.com.
282*cfb92d14SAndroid Build Coastguard Worker  * inst1
283*cfb92d14SAndroid Build Coastguard Worker  *     Port:1234, Priority:1, Weight:2, TTL:7200
284*cfb92d14SAndroid Build Coastguard Worker  *     Host:host.example.com.
285*cfb92d14SAndroid Build Coastguard Worker  *     HostAddress:fd00:0:0:0:0:0:0:abcd TTL:7200
286*cfb92d14SAndroid Build Coastguard Worker  *     TXT:[a=6531, b=6c12] TTL:7300
287*cfb92d14SAndroid Build Coastguard Worker  * instance2
288*cfb92d14SAndroid Build Coastguard Worker  *     Port:1234, Priority:1, Weight:2, TTL:7200
289*cfb92d14SAndroid Build Coastguard Worker  *     Host:host.example.com.
290*cfb92d14SAndroid Build Coastguard Worker  *     HostAddress:fd00:0:0:0:0:0:0:abcd TTL:7200
291*cfb92d14SAndroid Build Coastguard Worker  *     TXT:[a=1234] TTL:7300
292*cfb92d14SAndroid Build Coastguard Worker  * Done
293*cfb92d14SAndroid Build Coastguard Worker  * @endcode
294*cfb92d14SAndroid Build Coastguard Worker  * @code
295*cfb92d14SAndroid Build Coastguard Worker  * dns browse _airplay._tcp.default.service.arpa
296*cfb92d14SAndroid Build Coastguard Worker  * DNS browse response for _airplay._tcp.default.service.arpa.
297*cfb92d14SAndroid Build Coastguard Worker  * Mac mini
298*cfb92d14SAndroid Build Coastguard Worker  *     Port:7000, Priority:0, Weight:0, TTL:10
299*cfb92d14SAndroid Build Coastguard Worker  *     Host:Mac-mini.default.service.arpa.
300*cfb92d14SAndroid Build Coastguard Worker  *     HostAddress:fd97:739d:386a:1:1c2e:d83c:fcbe:9cf4 TTL:10
301*cfb92d14SAndroid Build Coastguard Worker  * Done
302*cfb92d14SAndroid Build Coastguard Worker  * @endcode
303*cfb92d14SAndroid Build Coastguard Worker  * @cparam dns browse @ca{service-name} [@ca{dns-server-IP}] [@ca{dns-server-port}] <!--
304*cfb92d14SAndroid Build Coastguard Worker  * -->                [@ca{response-timeout-ms}] [@ca{max-tx-attempts}] <!--
305*cfb92d14SAndroid Build Coastguard Worker  * -->                [@ca{recursion-desired-boolean}]
306*cfb92d14SAndroid Build Coastguard Worker  * @sa otDnsClientBrowse
307*cfb92d14SAndroid Build Coastguard Worker  * @par
308*cfb92d14SAndroid Build Coastguard Worker  * Send a browse (service instance enumeration) DNS query to get the list of services for
309*cfb92d14SAndroid Build Coastguard Worker  * given service-name
310*cfb92d14SAndroid Build Coastguard Worker  * @par
311*cfb92d14SAndroid Build Coastguard Worker  * The parameters after `service-name` are optional. Any unspecified (or zero) value
312*cfb92d14SAndroid Build Coastguard Worker  * for these optional parameters is replaced by the value from the current default
313*cfb92d14SAndroid Build Coastguard Worker  * config (`dns config`).
314*cfb92d14SAndroid Build Coastguard Worker  * @par
315*cfb92d14SAndroid Build Coastguard Worker  * Note: The DNS server IP can be an IPv4 address, which will be synthesized to an IPv6
316*cfb92d14SAndroid Build Coastguard Worker  * address using the preferred NAT64 prefix from the network data. The command will return
317*cfb92d14SAndroid Build Coastguard Worker  * `InvalidState` when the DNS server IP is an IPv4 address but the preferred NAT64 prefix
318*cfb92d14SAndroid Build Coastguard Worker  * is unavailable. When testing DNS-SD discovery proxy, the zone is not `local` and
319*cfb92d14SAndroid Build Coastguard Worker  * instead should be `default.service.arpa`.
320*cfb92d14SAndroid Build Coastguard Worker  * `OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE` is required.
321*cfb92d14SAndroid Build Coastguard Worker  */
Process(Arg aArgs[])322*cfb92d14SAndroid Build Coastguard Worker template <> otError Dns::Process<Cmd("browse")>(Arg aArgs[])
323*cfb92d14SAndroid Build Coastguard Worker {
324*cfb92d14SAndroid Build Coastguard Worker     otError           error = OT_ERROR_NONE;
325*cfb92d14SAndroid Build Coastguard Worker     otDnsQueryConfig  queryConfig;
326*cfb92d14SAndroid Build Coastguard Worker     otDnsQueryConfig *config = &queryConfig;
327*cfb92d14SAndroid Build Coastguard Worker 
328*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(!aArgs[0].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
329*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = GetDnsConfig(aArgs + 1, config));
330*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(
331*cfb92d14SAndroid Build Coastguard Worker         error = otDnsClientBrowse(GetInstancePtr(), aArgs[0].GetCString(), &HandleDnsBrowseResponse, this, config));
332*cfb92d14SAndroid Build Coastguard Worker     error = OT_ERROR_PENDING;
333*cfb92d14SAndroid Build Coastguard Worker 
334*cfb92d14SAndroid Build Coastguard Worker exit:
335*cfb92d14SAndroid Build Coastguard Worker     return error;
336*cfb92d14SAndroid Build Coastguard Worker }
337*cfb92d14SAndroid Build Coastguard Worker 
338*cfb92d14SAndroid Build Coastguard Worker /**
339*cfb92d14SAndroid Build Coastguard Worker  * @cli dns service
340*cfb92d14SAndroid Build Coastguard Worker  * @cparam dns service @ca{service-instance-label} @ca{service-name} <!--
341*cfb92d14SAndroid Build Coastguard Worker  * -->                 [@ca{DNS-server-IP}] [@ca{DNS-server-port}] <!--
342*cfb92d14SAndroid Build Coastguard Worker  * -->                 [@ca{response-timeout-ms}] [@ca{max-tx-attempts}] <!--
343*cfb92d14SAndroid Build Coastguard Worker  * -->                 [@ca{recursion-desired-boolean}]
344*cfb92d14SAndroid Build Coastguard Worker  * @par api_copy
345*cfb92d14SAndroid Build Coastguard Worker  * #otDnsClientResolveService
346*cfb92d14SAndroid Build Coastguard Worker  * @par
347*cfb92d14SAndroid Build Coastguard Worker  * Send a service instance resolution DNS query for a given service instance.
348*cfb92d14SAndroid Build Coastguard Worker  * Service instance label is provided first, followed by the service name
349*cfb92d14SAndroid Build Coastguard Worker  * (note that service instance label can contain dot '.' character).
350*cfb92d14SAndroid Build Coastguard Worker  * @par
351*cfb92d14SAndroid Build Coastguard Worker  * The parameters after `service-name` are optional. Any unspecified (or zero)
352*cfb92d14SAndroid Build Coastguard Worker  * value for these optional parameters is replaced by the value from the
353*cfb92d14SAndroid Build Coastguard Worker  * current default config (`dns config`).
354*cfb92d14SAndroid Build Coastguard Worker  * @par
355*cfb92d14SAndroid Build Coastguard Worker  * Note: The DNS server IP can be an IPv4 address, which will be synthesized
356*cfb92d14SAndroid Build Coastguard Worker  * to an IPv6 address using the preferred NAT64 prefix from the network data.
357*cfb92d14SAndroid Build Coastguard Worker  * The command will return `InvalidState` when the DNS server IP is an IPv4
358*cfb92d14SAndroid Build Coastguard Worker  * address but the preferred NAT64 prefix is unavailable.
359*cfb92d14SAndroid Build Coastguard Worker  * `OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE` is required.
360*cfb92d14SAndroid Build Coastguard Worker  */
Process(Arg aArgs[])361*cfb92d14SAndroid Build Coastguard Worker template <> otError Dns::Process<Cmd("service")>(Arg aArgs[])
362*cfb92d14SAndroid Build Coastguard Worker {
363*cfb92d14SAndroid Build Coastguard Worker     return ProcessService(aArgs, otDnsClientResolveService);
364*cfb92d14SAndroid Build Coastguard Worker }
365*cfb92d14SAndroid Build Coastguard Worker 
366*cfb92d14SAndroid Build Coastguard Worker /**
367*cfb92d14SAndroid Build Coastguard Worker  * @cli dns servicehost
368*cfb92d14SAndroid Build Coastguard Worker  * @cparam dns servicehost @ca{service-instance-label} @ca{service-name} <!--
369*cfb92d14SAndroid Build Coastguard Worker  * -->                 [@ca{DNS-server-IP}] [@ca{DNS-server-port}] <!--
370*cfb92d14SAndroid Build Coastguard Worker  * -->                 [@ca{response-timeout-ms}] [@ca{max-tx-attempts}] <!--
371*cfb92d14SAndroid Build Coastguard Worker  * -->                 [@ca{recursion-desired-boolean}]
372*cfb92d14SAndroid Build Coastguard Worker  * @par api_copy
373*cfb92d14SAndroid Build Coastguard Worker  * #otDnsClientResolveServiceAndHostAddress
374*cfb92d14SAndroid Build Coastguard Worker  * @par
375*cfb92d14SAndroid Build Coastguard Worker  * Send a service instance resolution DNS query for a given service instance
376*cfb92d14SAndroid Build Coastguard Worker  * with potential follow-up host name resolution.
377*cfb92d14SAndroid Build Coastguard Worker  * Service instance label is provided first, followed by the service name
378*cfb92d14SAndroid Build Coastguard Worker  * (note that service instance label can contain dot '.' character).
379*cfb92d14SAndroid Build Coastguard Worker  * @par
380*cfb92d14SAndroid Build Coastguard Worker  * The parameters after `service-name` are optional. Any unspecified (or zero)
381*cfb92d14SAndroid Build Coastguard Worker  * value for these optional parameters is replaced by the value from the
382*cfb92d14SAndroid Build Coastguard Worker  * current default config (`dns config`).
383*cfb92d14SAndroid Build Coastguard Worker  * @par
384*cfb92d14SAndroid Build Coastguard Worker  * Note: The DNS server IP can be an IPv4 address, which will be synthesized
385*cfb92d14SAndroid Build Coastguard Worker  * to an IPv6 address using the preferred NAT64 prefix from the network data.
386*cfb92d14SAndroid Build Coastguard Worker  * The command will return `InvalidState` when the DNS server IP is an IPv4
387*cfb92d14SAndroid Build Coastguard Worker  * address but the preferred NAT64 prefix is unavailable.
388*cfb92d14SAndroid Build Coastguard Worker  * `OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE` is required.
389*cfb92d14SAndroid Build Coastguard Worker  */
Process(Arg aArgs[])390*cfb92d14SAndroid Build Coastguard Worker template <> otError Dns::Process<Cmd("servicehost")>(Arg aArgs[])
391*cfb92d14SAndroid Build Coastguard Worker {
392*cfb92d14SAndroid Build Coastguard Worker     return ProcessService(aArgs, otDnsClientResolveServiceAndHostAddress);
393*cfb92d14SAndroid Build Coastguard Worker }
394*cfb92d14SAndroid Build Coastguard Worker 
ProcessService(Arg aArgs[],ResolveServiceFn aResolveServiceFn)395*cfb92d14SAndroid Build Coastguard Worker otError Dns::ProcessService(Arg aArgs[], ResolveServiceFn aResolveServiceFn)
396*cfb92d14SAndroid Build Coastguard Worker {
397*cfb92d14SAndroid Build Coastguard Worker     otError           error = OT_ERROR_NONE;
398*cfb92d14SAndroid Build Coastguard Worker     otDnsQueryConfig  queryConfig;
399*cfb92d14SAndroid Build Coastguard Worker     otDnsQueryConfig *config = &queryConfig;
400*cfb92d14SAndroid Build Coastguard Worker 
401*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(!aArgs[1].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
402*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = GetDnsConfig(aArgs + 2, config));
403*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = aResolveServiceFn(GetInstancePtr(), aArgs[0].GetCString(), aArgs[1].GetCString(),
404*cfb92d14SAndroid Build Coastguard Worker                                             &HandleDnsServiceResponse, this, config));
405*cfb92d14SAndroid Build Coastguard Worker     error = OT_ERROR_PENDING;
406*cfb92d14SAndroid Build Coastguard Worker 
407*cfb92d14SAndroid Build Coastguard Worker exit:
408*cfb92d14SAndroid Build Coastguard Worker     return error;
409*cfb92d14SAndroid Build Coastguard Worker }
410*cfb92d14SAndroid Build Coastguard Worker 
411*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
412*cfb92d14SAndroid Build Coastguard Worker 
413*cfb92d14SAndroid Build Coastguard Worker //----------------------------------------------------------------------------------------------------------------------
414*cfb92d14SAndroid Build Coastguard Worker 
OutputResult(otError aError)415*cfb92d14SAndroid Build Coastguard Worker void Dns::OutputResult(otError aError) { Interpreter::GetInterpreter().OutputResult(aError); }
416*cfb92d14SAndroid Build Coastguard Worker 
GetDnsConfig(Arg aArgs[],otDnsQueryConfig * & aConfig)417*cfb92d14SAndroid Build Coastguard Worker otError Dns::GetDnsConfig(Arg aArgs[], otDnsQueryConfig *&aConfig)
418*cfb92d14SAndroid Build Coastguard Worker {
419*cfb92d14SAndroid Build Coastguard Worker     // This method gets the optional DNS config from `aArgs[]`.
420*cfb92d14SAndroid Build Coastguard Worker     // The format: `[server IP address] [server port] [timeout]
421*cfb92d14SAndroid Build Coastguard Worker     // [max tx attempt] [recursion desired] [service mode]
422*cfb92d14SAndroid Build Coastguard Worker     // [transport]`
423*cfb92d14SAndroid Build Coastguard Worker 
424*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
425*cfb92d14SAndroid Build Coastguard Worker     bool    recursionDesired;
426*cfb92d14SAndroid Build Coastguard Worker     bool    nat64Synth;
427*cfb92d14SAndroid Build Coastguard Worker 
428*cfb92d14SAndroid Build Coastguard Worker     ClearAllBytes(*aConfig);
429*cfb92d14SAndroid Build Coastguard Worker 
430*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(!aArgs[0].IsEmpty(), aConfig = nullptr);
431*cfb92d14SAndroid Build Coastguard Worker 
432*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = ParseToIp6Address(GetInstancePtr(), aArgs[0], aConfig->mServerSockAddr.mAddress, nat64Synth));
433*cfb92d14SAndroid Build Coastguard Worker     if (nat64Synth)
434*cfb92d14SAndroid Build Coastguard Worker     {
435*cfb92d14SAndroid Build Coastguard Worker         OutputFormat("Synthesized IPv6 DNS server address: ");
436*cfb92d14SAndroid Build Coastguard Worker         OutputIp6AddressLine(aConfig->mServerSockAddr.mAddress);
437*cfb92d14SAndroid Build Coastguard Worker     }
438*cfb92d14SAndroid Build Coastguard Worker 
439*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(!aArgs[1].IsEmpty());
440*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = aArgs[1].ParseAsUint16(aConfig->mServerSockAddr.mPort));
441*cfb92d14SAndroid Build Coastguard Worker 
442*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(!aArgs[2].IsEmpty());
443*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = aArgs[2].ParseAsUint32(aConfig->mResponseTimeout));
444*cfb92d14SAndroid Build Coastguard Worker 
445*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(!aArgs[3].IsEmpty());
446*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = aArgs[3].ParseAsUint8(aConfig->mMaxTxAttempts));
447*cfb92d14SAndroid Build Coastguard Worker 
448*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(!aArgs[4].IsEmpty());
449*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = aArgs[4].ParseAsBool(recursionDesired));
450*cfb92d14SAndroid Build Coastguard Worker     aConfig->mRecursionFlag = recursionDesired ? OT_DNS_FLAG_RECURSION_DESIRED : OT_DNS_FLAG_NO_RECURSION;
451*cfb92d14SAndroid Build Coastguard Worker 
452*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(!aArgs[5].IsEmpty());
453*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = ParseDnsServiceMode(aArgs[5], aConfig->mServiceMode));
454*cfb92d14SAndroid Build Coastguard Worker 
455*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(!aArgs[6].IsEmpty());
456*cfb92d14SAndroid Build Coastguard Worker 
457*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[6] == "tcp")
458*cfb92d14SAndroid Build Coastguard Worker     {
459*cfb92d14SAndroid Build Coastguard Worker         aConfig->mTransportProto = OT_DNS_TRANSPORT_TCP;
460*cfb92d14SAndroid Build Coastguard Worker     }
461*cfb92d14SAndroid Build Coastguard Worker     else if (aArgs[6] == "udp")
462*cfb92d14SAndroid Build Coastguard Worker     {
463*cfb92d14SAndroid Build Coastguard Worker         aConfig->mTransportProto = OT_DNS_TRANSPORT_UDP;
464*cfb92d14SAndroid Build Coastguard Worker     }
465*cfb92d14SAndroid Build Coastguard Worker     else
466*cfb92d14SAndroid Build Coastguard Worker     {
467*cfb92d14SAndroid Build Coastguard Worker         error = OT_ERROR_INVALID_ARGS;
468*cfb92d14SAndroid Build Coastguard Worker     }
469*cfb92d14SAndroid Build Coastguard Worker 
470*cfb92d14SAndroid Build Coastguard Worker exit:
471*cfb92d14SAndroid Build Coastguard Worker     return error;
472*cfb92d14SAndroid Build Coastguard Worker }
473*cfb92d14SAndroid Build Coastguard Worker 
474*cfb92d14SAndroid Build Coastguard Worker const char *const Dns::kServiceModeStrings[] = {
475*cfb92d14SAndroid Build Coastguard Worker     "unspec",      // OT_DNS_SERVICE_MODE_UNSPECIFIED      (0)
476*cfb92d14SAndroid Build Coastguard Worker     "srv",         // OT_DNS_SERVICE_MODE_SRV              (1)
477*cfb92d14SAndroid Build Coastguard Worker     "txt",         // OT_DNS_SERVICE_MODE_TXT              (2)
478*cfb92d14SAndroid Build Coastguard Worker     "srv_txt",     // OT_DNS_SERVICE_MODE_SRV_TXT          (3)
479*cfb92d14SAndroid Build Coastguard Worker     "srv_txt_sep", // OT_DNS_SERVICE_MODE_SRV_TXT_SEPARATE (4)
480*cfb92d14SAndroid Build Coastguard Worker     "srv_txt_opt", // OT_DNS_SERVICE_MODE_SRV_TXT_OPTIMIZE (5)
481*cfb92d14SAndroid Build Coastguard Worker };
482*cfb92d14SAndroid Build Coastguard Worker 
483*cfb92d14SAndroid Build Coastguard Worker static_assert(OT_DNS_SERVICE_MODE_UNSPECIFIED == 0, "OT_DNS_SERVICE_MODE_UNSPECIFIED value is incorrect");
484*cfb92d14SAndroid Build Coastguard Worker static_assert(OT_DNS_SERVICE_MODE_SRV == 1, "OT_DNS_SERVICE_MODE_SRV value is incorrect");
485*cfb92d14SAndroid Build Coastguard Worker static_assert(OT_DNS_SERVICE_MODE_TXT == 2, "OT_DNS_SERVICE_MODE_TXT value is incorrect");
486*cfb92d14SAndroid Build Coastguard Worker static_assert(OT_DNS_SERVICE_MODE_SRV_TXT == 3, "OT_DNS_SERVICE_MODE_SRV_TXT value is incorrect");
487*cfb92d14SAndroid Build Coastguard Worker static_assert(OT_DNS_SERVICE_MODE_SRV_TXT_SEPARATE == 4, "OT_DNS_SERVICE_MODE_SRV_TXT_SEPARATE value is incorrect");
488*cfb92d14SAndroid Build Coastguard Worker static_assert(OT_DNS_SERVICE_MODE_SRV_TXT_OPTIMIZE == 5, "OT_DNS_SERVICE_MODE_SRV_TXT_OPTIMIZE value is incorrect");
489*cfb92d14SAndroid Build Coastguard Worker 
DnsConfigServiceModeToString(otDnsServiceMode aMode) const490*cfb92d14SAndroid Build Coastguard Worker const char *Dns::DnsConfigServiceModeToString(otDnsServiceMode aMode) const
491*cfb92d14SAndroid Build Coastguard Worker {
492*cfb92d14SAndroid Build Coastguard Worker     return Stringify(aMode, kServiceModeStrings);
493*cfb92d14SAndroid Build Coastguard Worker }
494*cfb92d14SAndroid Build Coastguard Worker 
ParseDnsServiceMode(const Arg & aArg,otDnsServiceMode & aMode) const495*cfb92d14SAndroid Build Coastguard Worker otError Dns::ParseDnsServiceMode(const Arg &aArg, otDnsServiceMode &aMode) const
496*cfb92d14SAndroid Build Coastguard Worker {
497*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
498*cfb92d14SAndroid Build Coastguard Worker 
499*cfb92d14SAndroid Build Coastguard Worker     if (aArg == "def")
500*cfb92d14SAndroid Build Coastguard Worker     {
501*cfb92d14SAndroid Build Coastguard Worker         aMode = OT_DNS_SERVICE_MODE_UNSPECIFIED;
502*cfb92d14SAndroid Build Coastguard Worker         ExitNow();
503*cfb92d14SAndroid Build Coastguard Worker     }
504*cfb92d14SAndroid Build Coastguard Worker 
505*cfb92d14SAndroid Build Coastguard Worker     for (size_t index = 0; index < OT_ARRAY_LENGTH(kServiceModeStrings); index++)
506*cfb92d14SAndroid Build Coastguard Worker     {
507*cfb92d14SAndroid Build Coastguard Worker         if (aArg == kServiceModeStrings[index])
508*cfb92d14SAndroid Build Coastguard Worker         {
509*cfb92d14SAndroid Build Coastguard Worker             aMode = static_cast<otDnsServiceMode>(index);
510*cfb92d14SAndroid Build Coastguard Worker             ExitNow();
511*cfb92d14SAndroid Build Coastguard Worker         }
512*cfb92d14SAndroid Build Coastguard Worker     }
513*cfb92d14SAndroid Build Coastguard Worker 
514*cfb92d14SAndroid Build Coastguard Worker     error = OT_ERROR_INVALID_ARGS;
515*cfb92d14SAndroid Build Coastguard Worker 
516*cfb92d14SAndroid Build Coastguard Worker exit:
517*cfb92d14SAndroid Build Coastguard Worker     return error;
518*cfb92d14SAndroid Build Coastguard Worker }
519*cfb92d14SAndroid Build Coastguard Worker 
HandleDnsAddressResponse(otError aError,const otDnsAddressResponse * aResponse,void * aContext)520*cfb92d14SAndroid Build Coastguard Worker void Dns::HandleDnsAddressResponse(otError aError, const otDnsAddressResponse *aResponse, void *aContext)
521*cfb92d14SAndroid Build Coastguard Worker {
522*cfb92d14SAndroid Build Coastguard Worker     static_cast<Dns *>(aContext)->HandleDnsAddressResponse(aError, aResponse);
523*cfb92d14SAndroid Build Coastguard Worker }
524*cfb92d14SAndroid Build Coastguard Worker 
HandleDnsAddressResponse(otError aError,const otDnsAddressResponse * aResponse)525*cfb92d14SAndroid Build Coastguard Worker void Dns::HandleDnsAddressResponse(otError aError, const otDnsAddressResponse *aResponse)
526*cfb92d14SAndroid Build Coastguard Worker {
527*cfb92d14SAndroid Build Coastguard Worker     char         hostName[OT_DNS_MAX_NAME_SIZE];
528*cfb92d14SAndroid Build Coastguard Worker     otIp6Address address;
529*cfb92d14SAndroid Build Coastguard Worker     uint32_t     ttl;
530*cfb92d14SAndroid Build Coastguard Worker 
531*cfb92d14SAndroid Build Coastguard Worker     IgnoreError(otDnsAddressResponseGetHostName(aResponse, hostName, sizeof(hostName)));
532*cfb92d14SAndroid Build Coastguard Worker 
533*cfb92d14SAndroid Build Coastguard Worker     OutputFormat("DNS response for %s - ", hostName);
534*cfb92d14SAndroid Build Coastguard Worker 
535*cfb92d14SAndroid Build Coastguard Worker     if (aError == OT_ERROR_NONE)
536*cfb92d14SAndroid Build Coastguard Worker     {
537*cfb92d14SAndroid Build Coastguard Worker         uint16_t index = 0;
538*cfb92d14SAndroid Build Coastguard Worker 
539*cfb92d14SAndroid Build Coastguard Worker         while (otDnsAddressResponseGetAddress(aResponse, index, &address, &ttl) == OT_ERROR_NONE)
540*cfb92d14SAndroid Build Coastguard Worker         {
541*cfb92d14SAndroid Build Coastguard Worker             OutputIp6Address(address);
542*cfb92d14SAndroid Build Coastguard Worker             OutputFormat(" TTL:%lu ", ToUlong(ttl));
543*cfb92d14SAndroid Build Coastguard Worker             index++;
544*cfb92d14SAndroid Build Coastguard Worker         }
545*cfb92d14SAndroid Build Coastguard Worker     }
546*cfb92d14SAndroid Build Coastguard Worker 
547*cfb92d14SAndroid Build Coastguard Worker     OutputNewLine();
548*cfb92d14SAndroid Build Coastguard Worker     OutputResult(aError);
549*cfb92d14SAndroid Build Coastguard Worker }
550*cfb92d14SAndroid Build Coastguard Worker 
551*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
552*cfb92d14SAndroid Build Coastguard Worker 
OutputDnsServiceInfo(uint8_t aIndentSize,const otDnsServiceInfo & aServiceInfo)553*cfb92d14SAndroid Build Coastguard Worker void Dns::OutputDnsServiceInfo(uint8_t aIndentSize, const otDnsServiceInfo &aServiceInfo)
554*cfb92d14SAndroid Build Coastguard Worker {
555*cfb92d14SAndroid Build Coastguard Worker     OutputLine(aIndentSize, "Port:%d, Priority:%d, Weight:%d, TTL:%lu", aServiceInfo.mPort, aServiceInfo.mPriority,
556*cfb92d14SAndroid Build Coastguard Worker                aServiceInfo.mWeight, ToUlong(aServiceInfo.mTtl));
557*cfb92d14SAndroid Build Coastguard Worker     OutputLine(aIndentSize, "Host:%s", aServiceInfo.mHostNameBuffer);
558*cfb92d14SAndroid Build Coastguard Worker     OutputFormat(aIndentSize, "HostAddress:");
559*cfb92d14SAndroid Build Coastguard Worker     OutputIp6Address(aServiceInfo.mHostAddress);
560*cfb92d14SAndroid Build Coastguard Worker     OutputLine(" TTL:%lu", ToUlong(aServiceInfo.mHostAddressTtl));
561*cfb92d14SAndroid Build Coastguard Worker     OutputFormat(aIndentSize, "TXT:");
562*cfb92d14SAndroid Build Coastguard Worker 
563*cfb92d14SAndroid Build Coastguard Worker     if (!aServiceInfo.mTxtDataTruncated)
564*cfb92d14SAndroid Build Coastguard Worker     {
565*cfb92d14SAndroid Build Coastguard Worker         OutputDnsTxtData(aServiceInfo.mTxtData, aServiceInfo.mTxtDataSize);
566*cfb92d14SAndroid Build Coastguard Worker     }
567*cfb92d14SAndroid Build Coastguard Worker     else
568*cfb92d14SAndroid Build Coastguard Worker     {
569*cfb92d14SAndroid Build Coastguard Worker         OutputFormat("[");
570*cfb92d14SAndroid Build Coastguard Worker         OutputBytes(aServiceInfo.mTxtData, aServiceInfo.mTxtDataSize);
571*cfb92d14SAndroid Build Coastguard Worker         OutputFormat("...]");
572*cfb92d14SAndroid Build Coastguard Worker     }
573*cfb92d14SAndroid Build Coastguard Worker 
574*cfb92d14SAndroid Build Coastguard Worker     OutputLine(" TTL:%lu", ToUlong(aServiceInfo.mTxtDataTtl));
575*cfb92d14SAndroid Build Coastguard Worker }
576*cfb92d14SAndroid Build Coastguard Worker 
HandleDnsBrowseResponse(otError aError,const otDnsBrowseResponse * aResponse,void * aContext)577*cfb92d14SAndroid Build Coastguard Worker void Dns::HandleDnsBrowseResponse(otError aError, const otDnsBrowseResponse *aResponse, void *aContext)
578*cfb92d14SAndroid Build Coastguard Worker {
579*cfb92d14SAndroid Build Coastguard Worker     static_cast<Dns *>(aContext)->HandleDnsBrowseResponse(aError, aResponse);
580*cfb92d14SAndroid Build Coastguard Worker }
581*cfb92d14SAndroid Build Coastguard Worker 
HandleDnsBrowseResponse(otError aError,const otDnsBrowseResponse * aResponse)582*cfb92d14SAndroid Build Coastguard Worker void Dns::HandleDnsBrowseResponse(otError aError, const otDnsBrowseResponse *aResponse)
583*cfb92d14SAndroid Build Coastguard Worker {
584*cfb92d14SAndroid Build Coastguard Worker     char             name[OT_DNS_MAX_NAME_SIZE];
585*cfb92d14SAndroid Build Coastguard Worker     char             label[OT_DNS_MAX_LABEL_SIZE];
586*cfb92d14SAndroid Build Coastguard Worker     uint8_t          txtBuffer[kMaxTxtDataSize];
587*cfb92d14SAndroid Build Coastguard Worker     otDnsServiceInfo serviceInfo;
588*cfb92d14SAndroid Build Coastguard Worker 
589*cfb92d14SAndroid Build Coastguard Worker     IgnoreError(otDnsBrowseResponseGetServiceName(aResponse, name, sizeof(name)));
590*cfb92d14SAndroid Build Coastguard Worker 
591*cfb92d14SAndroid Build Coastguard Worker     OutputLine("DNS browse response for %s", name);
592*cfb92d14SAndroid Build Coastguard Worker 
593*cfb92d14SAndroid Build Coastguard Worker     if (aError == OT_ERROR_NONE)
594*cfb92d14SAndroid Build Coastguard Worker     {
595*cfb92d14SAndroid Build Coastguard Worker         uint16_t index = 0;
596*cfb92d14SAndroid Build Coastguard Worker 
597*cfb92d14SAndroid Build Coastguard Worker         while (otDnsBrowseResponseGetServiceInstance(aResponse, index, label, sizeof(label)) == OT_ERROR_NONE)
598*cfb92d14SAndroid Build Coastguard Worker         {
599*cfb92d14SAndroid Build Coastguard Worker             OutputLine("%s", label);
600*cfb92d14SAndroid Build Coastguard Worker             index++;
601*cfb92d14SAndroid Build Coastguard Worker 
602*cfb92d14SAndroid Build Coastguard Worker             serviceInfo.mHostNameBuffer     = name;
603*cfb92d14SAndroid Build Coastguard Worker             serviceInfo.mHostNameBufferSize = sizeof(name);
604*cfb92d14SAndroid Build Coastguard Worker             serviceInfo.mTxtData            = txtBuffer;
605*cfb92d14SAndroid Build Coastguard Worker             serviceInfo.mTxtDataSize        = sizeof(txtBuffer);
606*cfb92d14SAndroid Build Coastguard Worker 
607*cfb92d14SAndroid Build Coastguard Worker             if (otDnsBrowseResponseGetServiceInfo(aResponse, label, &serviceInfo) == OT_ERROR_NONE)
608*cfb92d14SAndroid Build Coastguard Worker             {
609*cfb92d14SAndroid Build Coastguard Worker                 OutputDnsServiceInfo(kIndentSize, serviceInfo);
610*cfb92d14SAndroid Build Coastguard Worker             }
611*cfb92d14SAndroid Build Coastguard Worker 
612*cfb92d14SAndroid Build Coastguard Worker             OutputNewLine();
613*cfb92d14SAndroid Build Coastguard Worker         }
614*cfb92d14SAndroid Build Coastguard Worker     }
615*cfb92d14SAndroid Build Coastguard Worker 
616*cfb92d14SAndroid Build Coastguard Worker     OutputResult(aError);
617*cfb92d14SAndroid Build Coastguard Worker }
618*cfb92d14SAndroid Build Coastguard Worker 
HandleDnsServiceResponse(otError aError,const otDnsServiceResponse * aResponse,void * aContext)619*cfb92d14SAndroid Build Coastguard Worker void Dns::HandleDnsServiceResponse(otError aError, const otDnsServiceResponse *aResponse, void *aContext)
620*cfb92d14SAndroid Build Coastguard Worker {
621*cfb92d14SAndroid Build Coastguard Worker     static_cast<Dns *>(aContext)->HandleDnsServiceResponse(aError, aResponse);
622*cfb92d14SAndroid Build Coastguard Worker }
623*cfb92d14SAndroid Build Coastguard Worker 
HandleDnsServiceResponse(otError aError,const otDnsServiceResponse * aResponse)624*cfb92d14SAndroid Build Coastguard Worker void Dns::HandleDnsServiceResponse(otError aError, const otDnsServiceResponse *aResponse)
625*cfb92d14SAndroid Build Coastguard Worker {
626*cfb92d14SAndroid Build Coastguard Worker     char             name[OT_DNS_MAX_NAME_SIZE];
627*cfb92d14SAndroid Build Coastguard Worker     char             label[OT_DNS_MAX_LABEL_SIZE];
628*cfb92d14SAndroid Build Coastguard Worker     uint8_t          txtBuffer[kMaxTxtDataSize];
629*cfb92d14SAndroid Build Coastguard Worker     otDnsServiceInfo serviceInfo;
630*cfb92d14SAndroid Build Coastguard Worker 
631*cfb92d14SAndroid Build Coastguard Worker     IgnoreError(otDnsServiceResponseGetServiceName(aResponse, label, sizeof(label), name, sizeof(name)));
632*cfb92d14SAndroid Build Coastguard Worker 
633*cfb92d14SAndroid Build Coastguard Worker     OutputLine("DNS service resolution response for %s for service %s", label, name);
634*cfb92d14SAndroid Build Coastguard Worker 
635*cfb92d14SAndroid Build Coastguard Worker     if (aError == OT_ERROR_NONE)
636*cfb92d14SAndroid Build Coastguard Worker     {
637*cfb92d14SAndroid Build Coastguard Worker         serviceInfo.mHostNameBuffer     = name;
638*cfb92d14SAndroid Build Coastguard Worker         serviceInfo.mHostNameBufferSize = sizeof(name);
639*cfb92d14SAndroid Build Coastguard Worker         serviceInfo.mTxtData            = txtBuffer;
640*cfb92d14SAndroid Build Coastguard Worker         serviceInfo.mTxtDataSize        = sizeof(txtBuffer);
641*cfb92d14SAndroid Build Coastguard Worker 
642*cfb92d14SAndroid Build Coastguard Worker         if (otDnsServiceResponseGetServiceInfo(aResponse, &serviceInfo) == OT_ERROR_NONE)
643*cfb92d14SAndroid Build Coastguard Worker         {
644*cfb92d14SAndroid Build Coastguard Worker             OutputDnsServiceInfo(/* aIndentSize */ 0, serviceInfo);
645*cfb92d14SAndroid Build Coastguard Worker             OutputNewLine();
646*cfb92d14SAndroid Build Coastguard Worker         }
647*cfb92d14SAndroid Build Coastguard Worker     }
648*cfb92d14SAndroid Build Coastguard Worker 
649*cfb92d14SAndroid Build Coastguard Worker     OutputResult(aError);
650*cfb92d14SAndroid Build Coastguard Worker }
651*cfb92d14SAndroid Build Coastguard Worker 
652*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
653*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
654*cfb92d14SAndroid Build Coastguard Worker 
655*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE
656*cfb92d14SAndroid Build Coastguard Worker 
Process(Arg aArgs[])657*cfb92d14SAndroid Build Coastguard Worker template <> otError Dns::Process<Cmd("server")>(Arg aArgs[])
658*cfb92d14SAndroid Build Coastguard Worker {
659*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
660*cfb92d14SAndroid Build Coastguard Worker 
661*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0].IsEmpty())
662*cfb92d14SAndroid Build Coastguard Worker     {
663*cfb92d14SAndroid Build Coastguard Worker         error = OT_ERROR_INVALID_ARGS;
664*cfb92d14SAndroid Build Coastguard Worker     }
665*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_DNS_UPSTREAM_QUERY_ENABLE
666*cfb92d14SAndroid Build Coastguard Worker     /**
667*cfb92d14SAndroid Build Coastguard Worker      * @cli dns server upstream
668*cfb92d14SAndroid Build Coastguard Worker      * @code
669*cfb92d14SAndroid Build Coastguard Worker      * dns server upstream
670*cfb92d14SAndroid Build Coastguard Worker      * Enabled
671*cfb92d14SAndroid Build Coastguard Worker      * Done
672*cfb92d14SAndroid Build Coastguard Worker      * @endcode
673*cfb92d14SAndroid Build Coastguard Worker      * @par api_copy
674*cfb92d14SAndroid Build Coastguard Worker      * #otDnssdUpstreamQueryIsEnabled
675*cfb92d14SAndroid Build Coastguard Worker      */
676*cfb92d14SAndroid Build Coastguard Worker     else if (aArgs[0] == "upstream")
677*cfb92d14SAndroid Build Coastguard Worker     {
678*cfb92d14SAndroid Build Coastguard Worker         /**
679*cfb92d14SAndroid Build Coastguard Worker          * @cli dns server upstream {enable|disable}
680*cfb92d14SAndroid Build Coastguard Worker          * @code
681*cfb92d14SAndroid Build Coastguard Worker          * dns server upstream enable
682*cfb92d14SAndroid Build Coastguard Worker          * Done
683*cfb92d14SAndroid Build Coastguard Worker          * @endcode
684*cfb92d14SAndroid Build Coastguard Worker          * @cparam dns server upstream @ca{enable|disable}
685*cfb92d14SAndroid Build Coastguard Worker          * @par api_copy
686*cfb92d14SAndroid Build Coastguard Worker          * #otDnssdUpstreamQuerySetEnabled
687*cfb92d14SAndroid Build Coastguard Worker          */
688*cfb92d14SAndroid Build Coastguard Worker         error = ProcessEnableDisable(aArgs + 1, otDnssdUpstreamQueryIsEnabled, otDnssdUpstreamQuerySetEnabled);
689*cfb92d14SAndroid Build Coastguard Worker     }
690*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_DNS_UPSTREAM_QUERY_ENABLE
691*cfb92d14SAndroid Build Coastguard Worker     else
692*cfb92d14SAndroid Build Coastguard Worker     {
693*cfb92d14SAndroid Build Coastguard Worker         ExitNow(error = OT_ERROR_INVALID_COMMAND);
694*cfb92d14SAndroid Build Coastguard Worker     }
695*cfb92d14SAndroid Build Coastguard Worker 
696*cfb92d14SAndroid Build Coastguard Worker exit:
697*cfb92d14SAndroid Build Coastguard Worker     return error;
698*cfb92d14SAndroid Build Coastguard Worker }
699*cfb92d14SAndroid Build Coastguard Worker 
700*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE
701*cfb92d14SAndroid Build Coastguard Worker 
Process(Arg aArgs[])702*cfb92d14SAndroid Build Coastguard Worker otError Dns::Process(Arg aArgs[])
703*cfb92d14SAndroid Build Coastguard Worker {
704*cfb92d14SAndroid Build Coastguard Worker #define CmdEntry(aCommandString)                           \
705*cfb92d14SAndroid Build Coastguard Worker     {                                                      \
706*cfb92d14SAndroid Build Coastguard Worker         aCommandString, &Dns::Process<Cmd(aCommandString)> \
707*cfb92d14SAndroid Build Coastguard Worker     }
708*cfb92d14SAndroid Build Coastguard Worker 
709*cfb92d14SAndroid Build Coastguard Worker     static constexpr Command kCommands[] = {
710*cfb92d14SAndroid Build Coastguard Worker 
711*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE && OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
712*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("browse"),
713*cfb92d14SAndroid Build Coastguard Worker #endif
714*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
715*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("compression"),
716*cfb92d14SAndroid Build Coastguard Worker #endif
717*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
718*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("config"),
719*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("resolve"),
720*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
721*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("resolve4"),
722*cfb92d14SAndroid Build Coastguard Worker #endif
723*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
724*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE
725*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("server"),
726*cfb92d14SAndroid Build Coastguard Worker #endif
727*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE && OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
728*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("service"),
729*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("servicehost"),
730*cfb92d14SAndroid Build Coastguard Worker #endif
731*cfb92d14SAndroid Build Coastguard Worker     };
732*cfb92d14SAndroid Build Coastguard Worker 
733*cfb92d14SAndroid Build Coastguard Worker #undef CmdEntry
734*cfb92d14SAndroid Build Coastguard Worker 
735*cfb92d14SAndroid Build Coastguard Worker     static_assert(BinarySearch::IsSorted(kCommands), "kCommands is not sorted");
736*cfb92d14SAndroid Build Coastguard Worker 
737*cfb92d14SAndroid Build Coastguard Worker     otError        error = OT_ERROR_INVALID_COMMAND;
738*cfb92d14SAndroid Build Coastguard Worker     const Command *command;
739*cfb92d14SAndroid Build Coastguard Worker 
740*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0].IsEmpty() || (aArgs[0] == "help"))
741*cfb92d14SAndroid Build Coastguard Worker     {
742*cfb92d14SAndroid Build Coastguard Worker         OutputCommandTable(kCommands);
743*cfb92d14SAndroid Build Coastguard Worker         ExitNow(error = aArgs[0].IsEmpty() ? error : OT_ERROR_NONE);
744*cfb92d14SAndroid Build Coastguard Worker     }
745*cfb92d14SAndroid Build Coastguard Worker 
746*cfb92d14SAndroid Build Coastguard Worker     command = BinarySearch::Find(aArgs[0].GetCString(), kCommands);
747*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(command != nullptr);
748*cfb92d14SAndroid Build Coastguard Worker 
749*cfb92d14SAndroid Build Coastguard Worker     error = (this->*command->mHandler)(aArgs + 1);
750*cfb92d14SAndroid Build Coastguard Worker 
751*cfb92d14SAndroid Build Coastguard Worker exit:
752*cfb92d14SAndroid Build Coastguard Worker     return error;
753*cfb92d14SAndroid Build Coastguard Worker }
754*cfb92d14SAndroid Build Coastguard Worker 
755*cfb92d14SAndroid Build Coastguard Worker } // namespace Cli
756*cfb92d14SAndroid Build Coastguard Worker } // namespace ot
757*cfb92d14SAndroid Build Coastguard Worker 
758*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CLI_DNS_ENABLE
759