zephyr/subsys/net/lib/shell/net_shell.c
Jukka Rissanen b0d0f60389 net: shell: Print device and wifi information for iface cmd
If the interface is WiFi one, then print information about it.
Also the device information is useful to know so print device
name corresponding to the network interface.

Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
2023-11-06 15:51:36 -06:00

255 lines
5.4 KiB
C

/** @file
* @brief Network shell module
*
* Provide some networking shell commands that can be useful to applications.
*/
/*
* Copyright (c) 2016 Intel Corporation
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG);
#include <zephyr/kernel.h>
#include <zephyr/random/random.h>
#include <stdlib.h>
#include <zephyr/net/ethernet.h>
#include "common.h"
#include "net_shell.h"
int get_iface_idx(const struct shell *sh, char *index_str)
{
char *endptr;
int idx;
if (!index_str) {
PR_WARNING("Interface index is missing.\n");
return -EINVAL;
}
idx = strtol(index_str, &endptr, 10);
if (*endptr != '\0') {
PR_WARNING("Invalid index %s\n", index_str);
return -ENOENT;
}
if (idx < 0 || idx > 255) {
PR_WARNING("Invalid index %d\n", idx);
return -ERANGE;
}
return idx;
}
const char *addrtype2str(enum net_addr_type addr_type)
{
switch (addr_type) {
case NET_ADDR_ANY:
return "<unknown type>";
case NET_ADDR_AUTOCONF:
return "autoconf";
case NET_ADDR_DHCP:
return "DHCP";
case NET_ADDR_MANUAL:
return "manual";
case NET_ADDR_OVERRIDABLE:
return "overridable";
}
return "<invalid type>";
}
const char *addrstate2str(enum net_addr_state addr_state)
{
switch (addr_state) {
case NET_ADDR_ANY_STATE:
return "<unknown state>";
case NET_ADDR_TENTATIVE:
return "tentative";
case NET_ADDR_PREFERRED:
return "preferred";
case NET_ADDR_DEPRECATED:
return "deprecated";
}
return "<invalid state>";
}
#if defined(CONFIG_NET_OFFLOAD) || defined(CONFIG_NET_NATIVE)
void get_addresses(struct net_context *context,
char addr_local[], int local_len,
char addr_remote[], int remote_len)
{
if (IS_ENABLED(CONFIG_NET_IPV6) && context->local.family == AF_INET6) {
snprintk(addr_local, local_len, "[%s]:%u",
net_sprint_ipv6_addr(
net_sin6_ptr(&context->local)->sin6_addr),
ntohs(net_sin6_ptr(&context->local)->sin6_port));
snprintk(addr_remote, remote_len, "[%s]:%u",
net_sprint_ipv6_addr(
&net_sin6(&context->remote)->sin6_addr),
ntohs(net_sin6(&context->remote)->sin6_port));
} else if (IS_ENABLED(CONFIG_NET_IPV4) && context->local.family == AF_INET) {
snprintk(addr_local, local_len, "%s:%d",
net_sprint_ipv4_addr(
net_sin_ptr(&context->local)->sin_addr),
ntohs(net_sin_ptr(&context->local)->sin_port));
/* Check if we need to print the v4-mapping-to-v6 address */
if (IS_ENABLED(CONFIG_NET_IPV4_MAPPING_TO_IPV6) &&
net_sin(&context->remote)->sin_family == AF_INET6 &&
net_ipv6_addr_is_v4_mapped(&net_sin6(&context->remote)->sin6_addr)) {
snprintk(addr_remote, remote_len, "[%s]:%d",
net_sprint_ipv6_addr(
&net_sin6(&context->remote)->sin6_addr),
ntohs(net_sin6(&context->remote)->sin6_port));
} else {
snprintk(addr_remote, remote_len, "%s:%d",
net_sprint_ipv4_addr(
&net_sin(&context->remote)->sin_addr),
ntohs(net_sin(&context->remote)->sin_port));
}
} else if (context->local.family == AF_UNSPEC) {
snprintk(addr_local, local_len, "AF_UNSPEC");
} else if (context->local.family == AF_PACKET) {
snprintk(addr_local, local_len, "AF_PACKET");
} else if (context->local.family == AF_CAN) {
snprintk(addr_local, local_len, "AF_CAN");
} else {
snprintk(addr_local, local_len, "AF_UNK(%d)",
context->local.family);
}
}
#endif /* CONFIG_NET_OFFLOAD || CONFIG_NET_NATIVE */
const char *iface2str(struct net_if *iface, const char **extra)
{
#ifdef CONFIG_NET_L2_IEEE802154
if (net_if_l2(iface) == &NET_L2_GET_NAME(IEEE802154)) {
if (extra) {
*extra = "=============";
}
return "IEEE 802.15.4";
}
#endif
#ifdef CONFIG_NET_L2_ETHERNET
if (net_if_l2(iface) == &NET_L2_GET_NAME(ETHERNET)) {
struct ethernet_context *eth_ctx = net_if_l2_data(iface);
if (eth_ctx->eth_if_type == L2_ETH_IF_TYPE_WIFI) {
if (extra) {
*extra = "====";
}
return "WiFi";
}
if (extra) {
*extra = "========";
}
return "Ethernet";
}
#endif
#ifdef CONFIG_NET_L2_VIRTUAL
if (net_if_l2(iface) == &NET_L2_GET_NAME(VIRTUAL)) {
if (extra) {
*extra = "=======";
}
return "Virtual";
}
#endif
#ifdef CONFIG_NET_L2_PPP
if (net_if_l2(iface) == &NET_L2_GET_NAME(PPP)) {
if (extra) {
*extra = "===";
}
return "PPP";
}
#endif
#ifdef CONFIG_NET_L2_DUMMY
if (net_if_l2(iface) == &NET_L2_GET_NAME(DUMMY)) {
if (extra) {
*extra = "=====";
}
return "Dummy";
}
#endif
#ifdef CONFIG_NET_L2_OPENTHREAD
if (net_if_l2(iface) == &NET_L2_GET_NAME(OPENTHREAD)) {
if (extra) {
*extra = "==========";
}
return "OpenThread";
}
#endif
#ifdef CONFIG_NET_L2_BT
if (net_if_l2(iface) == &NET_L2_GET_NAME(BLUETOOTH)) {
if (extra) {
*extra = "=========";
}
return "Bluetooth";
}
#endif
#ifdef CONFIG_NET_OFFLOAD
if (net_if_is_ip_offloaded(iface)) {
if (extra) {
*extra = "==========";
}
return "IP Offload";
}
#endif
#ifdef CONFIG_NET_L2_CANBUS_RAW
if (net_if_l2(iface) == &NET_L2_GET_NAME(CANBUS_RAW)) {
if (extra) {
*extra = "==========";
}
return "CANBUS_RAW";
}
#endif
if (extra) {
*extra = "==============";
}
return "<unknown type>";
}
/* Placeholder for net commands that are configured in the rest of the .c files */
SHELL_SUBCMD_SET_CREATE(net_cmds, (net));
SHELL_CMD_REGISTER(net, &net_cmds, "Networking commands", NULL);
int net_shell_init(void)
{
if (IS_ENABLED(CONFIG_NET_MGMT_EVENT_MONITOR_AUTO_START)) {
events_enable();
}
return 0;
}