mirror of
https://github.com/espressif/openthread.git
synced 2026-08-07 19:27:46 +00:00
[cli] add netstat command (#5202)
This commit is contained in:
@@ -63,6 +63,7 @@ Done
|
||||
- [neighbor](#neighbor-list)
|
||||
- [netdataregister](#netdataregister)
|
||||
- [netdatashow](#netdatashow)
|
||||
- [netstat](#netstat)
|
||||
- [networkdiagnostic](#networkdiagnostic-get-addr-type-)
|
||||
- [networkidtimeout](#networkidtimeout)
|
||||
- [networkname](#networkname)
|
||||
@@ -1042,6 +1043,21 @@ Show Thread Leader network data.
|
||||
Done
|
||||
```
|
||||
|
||||
### netstat
|
||||
|
||||
List all UDP sockets.
|
||||
|
||||
```bash
|
||||
> netstat
|
||||
| Local Address | Peer Address |
|
||||
+-----------------------------------------------+-----------------------------------------------+
|
||||
| 0:0:0:0:0:0:0:0:49153 | 0:0:0:0:0:0:0:0:* |
|
||||
| 0:0:0:0:0:0:0:0:49152 | 0:0:0:0:0:0:0:0:* |
|
||||
| 0:0:0:0:0:0:0:0:61631 | 0:0:0:0:0:0:0:0:* |
|
||||
| 0:0:0:0:0:0:0:0:19788 | 0:0:0:0:0:0:0:0:* |
|
||||
Done
|
||||
```
|
||||
|
||||
### networkdiagnostic get \<addr\> \<type\> ..
|
||||
|
||||
Send network diagnostic request to retrieve tlv of \<type\>s.
|
||||
|
||||
+67
-2
@@ -193,6 +193,7 @@ const struct Command Interpreter::sCommands[] = {
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
|
||||
{"netif", &Interpreter::ProcessNetif},
|
||||
#endif
|
||||
{"netstat", &Interpreter::ProcessNetstat},
|
||||
#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
|
||||
{"networkdiagnostic", &Interpreter::ProcessNetworkDiagnostic},
|
||||
#endif // OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
|
||||
@@ -376,9 +377,9 @@ void Interpreter::OutputBytes(const uint8_t *aBytes, uint8_t aLength) const
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::OutputIp6Address(const otIp6Address &aAddress) const
|
||||
int Interpreter::OutputIp6Address(const otIp6Address &aAddress) const
|
||||
{
|
||||
mServer->OutputFormat(
|
||||
return mServer->OutputFormat(
|
||||
"%x:%x:%x:%x:%x:%x:%x:%x", HostSwap16(aAddress.mFields.m16[0]), HostSwap16(aAddress.mFields.m16[1]),
|
||||
HostSwap16(aAddress.mFields.m16[2]), HostSwap16(aAddress.mFields.m16[3]), HostSwap16(aAddress.mFields.m16[4]),
|
||||
HostSwap16(aAddress.mFields.m16[5]), HostSwap16(aAddress.mFields.m16[6]), HostSwap16(aAddress.mFields.m16[7]));
|
||||
@@ -2062,6 +2063,70 @@ exit:
|
||||
}
|
||||
#endif
|
||||
|
||||
void Interpreter::ProcessNetstat(uint8_t aArgsLength, char *aArgs[])
|
||||
{
|
||||
otUdpSocket *socket = otUdpGetSockets(mInstance);
|
||||
|
||||
OT_UNUSED_VARIABLE(aArgsLength);
|
||||
OT_UNUSED_VARIABLE(aArgs);
|
||||
|
||||
mServer->OutputFormat(
|
||||
"| Local Address | Peer Address |\n");
|
||||
mServer->OutputFormat(
|
||||
"+-----------------------------------------------+-----------------------------------------------+\n");
|
||||
|
||||
while (socket)
|
||||
{
|
||||
constexpr int kMaxOutputLength = 45;
|
||||
int outputLength;
|
||||
|
||||
mServer->OutputFormat("| ");
|
||||
|
||||
outputLength = OutputSocketAddress(socket->mSockName);
|
||||
for (int i = outputLength; 0 <= i && i < kMaxOutputLength; ++i)
|
||||
{
|
||||
mServer->OutputFormat(" ");
|
||||
}
|
||||
mServer->OutputFormat(" | ");
|
||||
|
||||
outputLength = OutputSocketAddress(socket->mPeerName);
|
||||
for (int i = outputLength; 0 <= i && i < kMaxOutputLength; ++i)
|
||||
{
|
||||
mServer->OutputFormat(" ");
|
||||
}
|
||||
mServer->OutputFormat(" |\n");
|
||||
|
||||
socket = socket->mNext;
|
||||
}
|
||||
|
||||
AppendResult(OT_ERROR_NONE);
|
||||
}
|
||||
|
||||
int Interpreter::OutputSocketAddress(const otSockAddr &aAddress)
|
||||
{
|
||||
int outputLength;
|
||||
int result = 0;
|
||||
|
||||
VerifyOrExit((outputLength = OutputIp6Address(aAddress.mAddress)) >= 0, result = -1);
|
||||
result += outputLength;
|
||||
|
||||
VerifyOrExit((outputLength = mServer->OutputFormat(":")) >= 0, result = -1);
|
||||
result += outputLength;
|
||||
if (aAddress.mPort == 0)
|
||||
{
|
||||
VerifyOrExit((outputLength = mServer->OutputFormat("*")) >= 0, result = -1);
|
||||
result += outputLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrExit((outputLength = mServer->OutputFormat("%d", aAddress.mPort)) >= 0, result = -1);
|
||||
result += outputLength;
|
||||
}
|
||||
|
||||
exit:
|
||||
return result;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
|
||||
void Interpreter::ProcessService(uint8_t aArgsLength, char *aArgs[])
|
||||
{
|
||||
|
||||
+8
-1
@@ -177,8 +177,13 @@ public:
|
||||
* Write an IPv6 address to the CLI console.
|
||||
*
|
||||
* @param[in] aAddress A reference to the IPv6 address.
|
||||
*
|
||||
* @returns The number of bytes placed in the output queue.
|
||||
*
|
||||
* @retval -1 Driver is broken.
|
||||
*
|
||||
*/
|
||||
void OutputIp6Address(const otIp6Address &aAddress) const;
|
||||
int OutputIp6Address(const otIp6Address &aAddress) const;
|
||||
|
||||
/**
|
||||
* Set a user command table.
|
||||
@@ -293,6 +298,8 @@ private:
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
|
||||
void ProcessNetif(uint8_t aArgsLength, char *aArgs[]);
|
||||
#endif
|
||||
void ProcessNetstat(uint8_t aArgsLength, char *aArgs[]);
|
||||
int OutputSocketAddress(const otSockAddr &aAddress);
|
||||
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
|
||||
void ProcessService(uint8_t aArgsLength, char *aArgs[]);
|
||||
#endif
|
||||
|
||||
@@ -119,14 +119,12 @@ void otUdpForwardReceive(otInstance * aInstance,
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
|
||||
otUdpSocket *otUdpGetSockets(otInstance *aInstance)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<Ip6::Udp>().GetUdpSockets();
|
||||
}
|
||||
#endif
|
||||
|
||||
otError otUdpAddReceiver(otInstance *aInstance, otUdpReceiver *aUdpReceiver)
|
||||
{
|
||||
|
||||
@@ -124,12 +124,19 @@ otError Udp::Socket::Connect(const SockAddr &aSockAddr)
|
||||
|
||||
mPeerName = aSockAddr;
|
||||
|
||||
if (!IsBound())
|
||||
{
|
||||
SuccessOrExit(error = Bind(GetSockName()));
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
|
||||
if (!IsMle(GetInstance(), mSockName.mPort))
|
||||
{
|
||||
error = otPlatUdpConnect(this);
|
||||
}
|
||||
#endif
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@@ -425,7 +425,6 @@ public:
|
||||
*/
|
||||
void UpdateChecksum(Message &aMessage, uint16_t aChecksum);
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
|
||||
/**
|
||||
* This method returns the head of UDP Sockets list.
|
||||
*
|
||||
@@ -433,7 +432,6 @@ public:
|
||||
*
|
||||
*/
|
||||
Socket *GetUdpSockets(void) { return mSockets.GetHead(); }
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE
|
||||
/**
|
||||
|
||||
Executable
+63
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/expect -f
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
source "tests/scripts/expect/_common.exp"
|
||||
|
||||
set timeout 3
|
||||
set spawn_id [spawn_node 1]
|
||||
|
||||
send "ifconfig up\n"
|
||||
expect "Done"
|
||||
send "udp open\n"
|
||||
expect "Done"
|
||||
send "netstat\n"
|
||||
expect "| Local Address | Peer Address |"
|
||||
expect "+-----------------------------------------------+-----------------------------------------------+"
|
||||
expect "| 0:0:0:0:0:0:0:0:* | 0:0:0:0:0:0:0:0:* |"
|
||||
expect "Done"
|
||||
send "udp bind :: 10001\n"
|
||||
expect "Done"
|
||||
send "netstat\n"
|
||||
expect "| Local Address | Peer Address |"
|
||||
expect "+-----------------------------------------------+-----------------------------------------------+"
|
||||
expect "| 0:0:0:0:0:0:0:0:10001 | 0:0:0:0:0:0:0:0:* |"
|
||||
expect "Done"
|
||||
send "ipaddr mleid\n"
|
||||
expect "ipaddr mleid"
|
||||
expect -re {(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4})}
|
||||
set addr $expect_out(1,string)
|
||||
send "udp connect $addr 10001\n"
|
||||
expect "Done"
|
||||
send "netstat\n"
|
||||
expect "| Local Address | Peer Address |"
|
||||
expect "+-----------------------------------------------+-----------------------------------------------+"
|
||||
expect -re "\\| 0:0:0:0:0:0:0:0:10001 +\\| $addr:10001 +\\|"
|
||||
expect "Done"
|
||||
|
||||
dispose
|
||||
Reference in New Issue
Block a user