371 lines
11 KiB
C++
371 lines
11 KiB
C++
/*
|
|
* Copyright (c) 2020, 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.
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
* This file implements a simple CLI for the SRP server.
|
|
*/
|
|
|
|
#include "cli_srp_server.hpp"
|
|
|
|
#include <inttypes.h>
|
|
|
|
#include "cli/cli.hpp"
|
|
#include "common/string.hpp"
|
|
|
|
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
|
|
|
|
namespace ot {
|
|
namespace Cli {
|
|
|
|
constexpr SrpServer::Command SrpServer::sCommands[];
|
|
|
|
otError SrpServer::Process(Arg aArgs[])
|
|
{
|
|
otError error = OT_ERROR_INVALID_COMMAND;
|
|
const Command *command;
|
|
|
|
if (aArgs[0].IsEmpty())
|
|
{
|
|
IgnoreError(ProcessHelp(aArgs));
|
|
ExitNow();
|
|
}
|
|
|
|
command = BinarySearch::Find(aArgs[0].GetCString(), sCommands);
|
|
VerifyOrExit(command != nullptr);
|
|
|
|
error = (this->*command->mHandler)(aArgs + 1);
|
|
|
|
exit:
|
|
return error;
|
|
}
|
|
|
|
otError SrpServer::ProcessAddrMode(Arg aArgs[])
|
|
{
|
|
otError error = OT_ERROR_INVALID_ARGS;
|
|
|
|
if (aArgs[0].IsEmpty())
|
|
{
|
|
switch (otSrpServerGetAddressMode(GetInstancePtr()))
|
|
{
|
|
case OT_SRP_SERVER_ADDRESS_MODE_UNICAST:
|
|
OutputLine("unicast");
|
|
break;
|
|
|
|
case OT_SRP_SERVER_ADDRESS_MODE_ANYCAST:
|
|
OutputLine("anycast");
|
|
break;
|
|
}
|
|
|
|
error = OT_ERROR_NONE;
|
|
}
|
|
else if (aArgs[0] == "unicast")
|
|
{
|
|
error = otSrpServerSetAddressMode(GetInstancePtr(), OT_SRP_SERVER_ADDRESS_MODE_UNICAST);
|
|
}
|
|
else if (aArgs[0] == "anycast")
|
|
{
|
|
error = otSrpServerSetAddressMode(GetInstancePtr(), OT_SRP_SERVER_ADDRESS_MODE_ANYCAST);
|
|
}
|
|
|
|
return error;
|
|
}
|
|
|
|
otError SrpServer::ProcessDomain(Arg aArgs[])
|
|
{
|
|
otError error = OT_ERROR_NONE;
|
|
|
|
if (aArgs[0].IsEmpty())
|
|
{
|
|
OutputLine("%s", otSrpServerGetDomain(GetInstancePtr()));
|
|
}
|
|
else
|
|
{
|
|
error = otSrpServerSetDomain(GetInstancePtr(), aArgs[0].GetCString());
|
|
}
|
|
|
|
return error;
|
|
}
|
|
|
|
otError SrpServer::ProcessState(Arg aArgs[])
|
|
{
|
|
static const char *const kStateStrings[] = {
|
|
"disabled", // (0) OT_SRP_SERVER_STATE_DISABLED
|
|
"running", // (1) OT_SRP_SERVER_STATE_RUNNING
|
|
"stopped", // (2) OT_SRP_SERVER_STATE_STOPPED
|
|
};
|
|
|
|
OT_UNUSED_VARIABLE(aArgs);
|
|
|
|
static_assert(0 == OT_SRP_SERVER_STATE_DISABLED, "OT_SRP_SERVER_STATE_DISABLED value is incorrect");
|
|
static_assert(1 == OT_SRP_SERVER_STATE_RUNNING, "OT_SRP_SERVER_STATE_RUNNING value is incorrect");
|
|
static_assert(2 == OT_SRP_SERVER_STATE_STOPPED, "OT_SRP_SERVER_STATE_STOPPED value is incorrect");
|
|
|
|
OutputLine("%s", Stringify(otSrpServerGetState(GetInstancePtr()), kStateStrings));
|
|
|
|
return OT_ERROR_NONE;
|
|
}
|
|
|
|
otError SrpServer::ProcessEnable(Arg aArgs[])
|
|
{
|
|
OT_UNUSED_VARIABLE(aArgs);
|
|
|
|
otSrpServerSetEnabled(GetInstancePtr(), /* aEnabled */ true);
|
|
|
|
return OT_ERROR_NONE;
|
|
}
|
|
|
|
otError SrpServer::ProcessDisable(Arg aArgs[])
|
|
{
|
|
OT_UNUSED_VARIABLE(aArgs);
|
|
|
|
otSrpServerSetEnabled(GetInstancePtr(), /* aEnabled */ false);
|
|
|
|
return OT_ERROR_NONE;
|
|
}
|
|
|
|
otError SrpServer::ProcessTtl(Arg aArgs[])
|
|
{
|
|
otError error = OT_ERROR_NONE;
|
|
otSrpServerTtlConfig ttlConfig;
|
|
|
|
if (aArgs[0].IsEmpty())
|
|
{
|
|
otSrpServerGetTtlConfig(GetInstancePtr(), &ttlConfig);
|
|
OutputLine("min ttl: %u", ttlConfig.mMinTtl);
|
|
OutputLine("max ttl: %u", ttlConfig.mMaxTtl);
|
|
}
|
|
else
|
|
{
|
|
SuccessOrExit(error = aArgs[0].ParseAsUint32(ttlConfig.mMinTtl));
|
|
SuccessOrExit(error = aArgs[1].ParseAsUint32(ttlConfig.mMaxTtl));
|
|
VerifyOrExit(aArgs[2].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
|
|
|
|
error = otSrpServerSetTtlConfig(GetInstancePtr(), &ttlConfig);
|
|
}
|
|
|
|
exit:
|
|
return error;
|
|
}
|
|
|
|
otError SrpServer::ProcessLease(Arg aArgs[])
|
|
{
|
|
otError error = OT_ERROR_NONE;
|
|
otSrpServerLeaseConfig leaseConfig;
|
|
|
|
if (aArgs[0].IsEmpty())
|
|
{
|
|
otSrpServerGetLeaseConfig(GetInstancePtr(), &leaseConfig);
|
|
OutputLine("min lease: %u", leaseConfig.mMinLease);
|
|
OutputLine("max lease: %u", leaseConfig.mMaxLease);
|
|
OutputLine("min key-lease: %u", leaseConfig.mMinKeyLease);
|
|
OutputLine("max key-lease: %u", leaseConfig.mMaxKeyLease);
|
|
}
|
|
else
|
|
{
|
|
SuccessOrExit(error = aArgs[0].ParseAsUint32(leaseConfig.mMinLease));
|
|
SuccessOrExit(error = aArgs[1].ParseAsUint32(leaseConfig.mMaxLease));
|
|
SuccessOrExit(error = aArgs[2].ParseAsUint32(leaseConfig.mMinKeyLease));
|
|
SuccessOrExit(error = aArgs[3].ParseAsUint32(leaseConfig.mMaxKeyLease));
|
|
VerifyOrExit(aArgs[4].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
|
|
|
|
error = otSrpServerSetLeaseConfig(GetInstancePtr(), &leaseConfig);
|
|
}
|
|
|
|
exit:
|
|
return error;
|
|
}
|
|
|
|
otError SrpServer::ProcessHost(Arg aArgs[])
|
|
{
|
|
otError error = OT_ERROR_NONE;
|
|
const otSrpServerHost *host;
|
|
|
|
VerifyOrExit(aArgs[0].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
|
|
|
|
host = nullptr;
|
|
while ((host = otSrpServerGetNextHost(GetInstancePtr(), host)) != nullptr)
|
|
{
|
|
const otIp6Address *addresses;
|
|
uint8_t addressesNum;
|
|
bool isDeleted = otSrpServerHostIsDeleted(host);
|
|
|
|
OutputLine("%s", otSrpServerHostGetFullName(host));
|
|
OutputLine(kIndentSize, "deleted: %s", isDeleted ? "true" : "false");
|
|
if (isDeleted)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
OutputSpaces(kIndentSize);
|
|
OutputFormat("addresses: [");
|
|
|
|
addresses = otSrpServerHostGetAddresses(host, &addressesNum);
|
|
|
|
for (uint8_t i = 0; i < addressesNum; ++i)
|
|
{
|
|
OutputIp6Address(addresses[i]);
|
|
if (i < addressesNum - 1)
|
|
{
|
|
OutputFormat(", ");
|
|
}
|
|
}
|
|
|
|
OutputLine("]");
|
|
}
|
|
|
|
exit:
|
|
return error;
|
|
}
|
|
|
|
void SrpServer::OutputHostAddresses(const otSrpServerHost *aHost)
|
|
{
|
|
const otIp6Address *addresses;
|
|
uint8_t addressesNum;
|
|
|
|
addresses = otSrpServerHostGetAddresses(aHost, &addressesNum);
|
|
|
|
OutputFormat("[");
|
|
for (uint8_t i = 0; i < addressesNum; ++i)
|
|
{
|
|
if (i != 0)
|
|
{
|
|
OutputFormat(", ");
|
|
}
|
|
|
|
OutputIp6Address(addresses[i]);
|
|
}
|
|
OutputFormat("]");
|
|
}
|
|
|
|
otError SrpServer::ProcessService(Arg aArgs[])
|
|
{
|
|
static constexpr char *kAnyServiceName = nullptr;
|
|
static constexpr char *kAnyInstanceName = nullptr;
|
|
|
|
otError error = OT_ERROR_NONE;
|
|
const otSrpServerHost *host = nullptr;
|
|
|
|
VerifyOrExit(aArgs[0].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
|
|
|
|
while ((host = otSrpServerGetNextHost(GetInstancePtr(), host)) != nullptr)
|
|
{
|
|
const otSrpServerService *service = nullptr;
|
|
|
|
while ((service = otSrpServerHostFindNextService(host, service, OT_SRP_SERVER_FLAGS_BASE_TYPE_SERVICE_ONLY,
|
|
kAnyServiceName, kAnyInstanceName)) != nullptr)
|
|
{
|
|
bool isDeleted = otSrpServerServiceIsDeleted(service);
|
|
const char * instanceName = otSrpServerServiceGetInstanceName(service);
|
|
const otSrpServerService *subService = nullptr;
|
|
const uint8_t * txtData;
|
|
uint16_t txtDataLength;
|
|
bool hasSubType = false;
|
|
|
|
OutputLine("%s", instanceName);
|
|
OutputLine(kIndentSize, "deleted: %s", isDeleted ? "true" : "false");
|
|
|
|
if (isDeleted)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
OutputFormat(kIndentSize, "subtypes: ");
|
|
|
|
while ((subService = otSrpServerHostFindNextService(
|
|
host, subService, (OT_SRP_SERVER_SERVICE_FLAG_SUB_TYPE | OT_SRP_SERVER_SERVICE_FLAG_ACTIVE),
|
|
kAnyServiceName, instanceName)) != nullptr)
|
|
{
|
|
char subLabel[OT_DNS_MAX_LABEL_SIZE];
|
|
|
|
IgnoreError(otSrpServerServiceGetServiceSubTypeLabel(subService, subLabel, sizeof(subLabel)));
|
|
OutputFormat("%s%s", hasSubType ? "," : "", subLabel);
|
|
hasSubType = true;
|
|
}
|
|
|
|
OutputLine(hasSubType ? "" : "(null)");
|
|
|
|
OutputLine(kIndentSize, "port: %hu", otSrpServerServiceGetPort(service));
|
|
OutputLine(kIndentSize, "priority: %hu", otSrpServerServiceGetPriority(service));
|
|
OutputLine(kIndentSize, "weight: %hu", otSrpServerServiceGetWeight(service));
|
|
OutputLine(kIndentSize, "ttl: %hu", otSrpServerServiceGetTtl(service));
|
|
|
|
txtData = otSrpServerServiceGetTxtData(service, &txtDataLength);
|
|
OutputFormat(kIndentSize, "TXT: ");
|
|
OutputDnsTxtData(txtData, txtDataLength);
|
|
OutputLine("");
|
|
|
|
OutputLine(kIndentSize, "host: %s", otSrpServerHostGetFullName(host));
|
|
|
|
OutputFormat(kIndentSize, "addresses: ");
|
|
OutputHostAddresses(host);
|
|
OutputLine("");
|
|
}
|
|
}
|
|
|
|
exit:
|
|
return error;
|
|
}
|
|
|
|
otError SrpServer::ProcessSeqNum(Arg aArgs[])
|
|
{
|
|
otError error = OT_ERROR_NONE;
|
|
|
|
if (aArgs[0].IsEmpty())
|
|
{
|
|
OutputLine("%u", otSrpServerGetAnycastModeSequenceNumber(GetInstancePtr()));
|
|
}
|
|
else
|
|
{
|
|
uint8_t sequenceNumber;
|
|
|
|
SuccessOrExit(error = aArgs[0].ParseAsUint8(sequenceNumber));
|
|
error = otSrpServerSetAnycastModeSequenceNumber(GetInstancePtr(), sequenceNumber);
|
|
}
|
|
|
|
exit:
|
|
return error;
|
|
}
|
|
|
|
otError SrpServer::ProcessHelp(Arg aArgs[])
|
|
{
|
|
OT_UNUSED_VARIABLE(aArgs);
|
|
|
|
for (const Command &command : sCommands)
|
|
{
|
|
OutputLine(command.mName);
|
|
}
|
|
|
|
return OT_ERROR_NONE;
|
|
}
|
|
|
|
} // namespace Cli
|
|
} // namespace ot
|
|
|
|
#endif // OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
|