The "net conn" command printed AF_PACKET socket as AF_UNK(3). Fix this by printing "AF_PACKET" in this case. Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
300 lines
8.0 KiB
C
300 lines
8.0 KiB
C
/*
|
|
* Copyright (c) 2016 Intel Corporation
|
|
* Copyright (c) 2023 Nordic Semiconductor ASA
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr/logging/log.h>
|
|
LOG_MODULE_DECLARE(net_shell);
|
|
|
|
#include "net_shell_private.h"
|
|
|
|
#if defined(CONFIG_NET_TCP)
|
|
#include "tcp_internal.h"
|
|
#include <zephyr/sys/slist.h>
|
|
#endif
|
|
|
|
#if defined(CONFIG_NET_OFFLOAD) || defined(CONFIG_NET_NATIVE)
|
|
static void context_cb(struct net_context *context, void *user_data)
|
|
{
|
|
#if defined(CONFIG_NET_IPV6) && !defined(CONFIG_NET_IPV4)
|
|
#define ADDR_LEN NET_IPV6_ADDR_LEN
|
|
#elif defined(CONFIG_NET_IPV4) && !defined(CONFIG_NET_IPV6)
|
|
#define ADDR_LEN NET_IPV4_ADDR_LEN
|
|
#else
|
|
#define ADDR_LEN NET_IPV6_ADDR_LEN
|
|
#endif
|
|
struct net_shell_user_data *data = user_data;
|
|
const struct shell *sh = data->sh;
|
|
int *count = data->user_data;
|
|
/* +7 for []:port */
|
|
char addr_local[ADDR_LEN + 7];
|
|
char addr_remote[ADDR_LEN + 7] = "";
|
|
|
|
get_addresses(context, addr_local, sizeof(addr_local),
|
|
addr_remote, sizeof(addr_remote));
|
|
|
|
PR("[%2d] %p\t%d %c%c%c %16s\t%16s\n",
|
|
(*count) + 1, context,
|
|
net_if_get_by_iface(net_context_get_iface(context)),
|
|
net_context_get_family(context) == AF_INET6 ? '6' :
|
|
(net_context_get_family(context) == AF_INET ? '4' : ' '),
|
|
net_context_get_type(context) == SOCK_DGRAM ? 'D' :
|
|
(net_context_get_type(context) == SOCK_STREAM ? 'S' :
|
|
(net_context_get_type(context) == SOCK_RAW ? 'R' : ' ')),
|
|
net_context_get_proto(context) == IPPROTO_UDP ? 'U' :
|
|
(net_context_get_proto(context) == IPPROTO_TCP ? 'T' : ' '),
|
|
addr_local, addr_remote);
|
|
|
|
(*count)++;
|
|
}
|
|
#endif /* CONFIG_NET_OFFLOAD || CONFIG_NET_NATIVE */
|
|
|
|
static void conn_handler_cb(struct net_conn *conn, void *user_data)
|
|
{
|
|
#if defined(CONFIG_NET_IPV6) && !defined(CONFIG_NET_IPV4)
|
|
#define ADDR_LEN NET_IPV6_ADDR_LEN
|
|
#elif defined(CONFIG_NET_IPV4) && !defined(CONFIG_NET_IPV6)
|
|
#define ADDR_LEN NET_IPV4_ADDR_LEN
|
|
#else
|
|
#define ADDR_LEN NET_IPV6_ADDR_LEN
|
|
#endif
|
|
struct net_shell_user_data *data = user_data;
|
|
const struct shell *sh = data->sh;
|
|
int *count = data->user_data;
|
|
/* +7 for []:port */
|
|
char addr_local[ADDR_LEN + 7];
|
|
char addr_remote[ADDR_LEN + 7] = "";
|
|
|
|
if (IS_ENABLED(CONFIG_NET_IPV6) && conn->local_addr.sa_family == AF_INET6) {
|
|
snprintk(addr_local, sizeof(addr_local), "[%s]:%u",
|
|
net_sprint_ipv6_addr(
|
|
&net_sin6(&conn->local_addr)->sin6_addr),
|
|
ntohs(net_sin6(&conn->local_addr)->sin6_port));
|
|
snprintk(addr_remote, sizeof(addr_remote), "[%s]:%u",
|
|
net_sprint_ipv6_addr(
|
|
&net_sin6(&conn->remote_addr)->sin6_addr),
|
|
ntohs(net_sin6(&conn->remote_addr)->sin6_port));
|
|
|
|
} else if (IS_ENABLED(CONFIG_NET_IPV4) && conn->local_addr.sa_family == AF_INET) {
|
|
snprintk(addr_local, sizeof(addr_local), "%s:%d",
|
|
net_sprint_ipv4_addr(
|
|
&net_sin(&conn->local_addr)->sin_addr),
|
|
ntohs(net_sin(&conn->local_addr)->sin_port));
|
|
snprintk(addr_remote, sizeof(addr_remote), "%s:%d",
|
|
net_sprint_ipv4_addr(
|
|
&net_sin(&conn->remote_addr)->sin_addr),
|
|
ntohs(net_sin(&conn->remote_addr)->sin_port));
|
|
|
|
} else if (conn->local_addr.sa_family == AF_UNSPEC) {
|
|
snprintk(addr_local, sizeof(addr_local), "AF_UNSPEC");
|
|
} else if (conn->local_addr.sa_family == AF_PACKET) {
|
|
snprintk(addr_local, sizeof(addr_local), "AF_PACKET");
|
|
} else {
|
|
snprintk(addr_local, sizeof(addr_local), "AF_UNK(%d)",
|
|
conn->local_addr.sa_family);
|
|
}
|
|
|
|
PR("[%2d] %p %p %s\t%16s\t%16s\n",
|
|
(*count) + 1, conn, conn->cb,
|
|
net_proto2str(conn->local_addr.sa_family, conn->proto),
|
|
addr_local, addr_remote);
|
|
|
|
(*count)++;
|
|
}
|
|
|
|
#if CONFIG_NET_TCP_LOG_LEVEL >= LOG_LEVEL_DBG
|
|
struct tcp_detail_info {
|
|
int printed_send_queue_header;
|
|
int printed_details;
|
|
int count;
|
|
};
|
|
#endif
|
|
|
|
#if defined(CONFIG_NET_TCP) && \
|
|
(defined(CONFIG_NET_OFFLOAD) || defined(CONFIG_NET_NATIVE))
|
|
static void tcp_cb(struct tcp *conn, void *user_data)
|
|
{
|
|
struct net_shell_user_data *data = user_data;
|
|
const struct shell *sh = data->sh;
|
|
int *count = data->user_data;
|
|
uint16_t recv_mss = net_tcp_get_supported_mss(conn);
|
|
|
|
PR("%p %p %5u %5u %10u %10u %5u %s\n",
|
|
conn, conn->context,
|
|
ntohs(net_sin6_ptr(&conn->context->local)->sin6_port),
|
|
ntohs(net_sin6(&conn->context->remote)->sin6_port),
|
|
conn->seq, conn->ack, recv_mss,
|
|
net_tcp_state_str(net_tcp_get_state(conn)));
|
|
|
|
(*count)++;
|
|
}
|
|
|
|
#if CONFIG_NET_TCP_LOG_LEVEL >= LOG_LEVEL_DBG
|
|
static void tcp_sent_list_cb(struct tcp *conn, void *user_data)
|
|
{
|
|
struct net_shell_user_data *data = user_data;
|
|
const struct shell *sh = data->sh;
|
|
struct tcp_detail_info *details = data->user_data;
|
|
struct net_pkt *pkt;
|
|
sys_snode_t *node;
|
|
|
|
if (conn->state != TCP_LISTEN) {
|
|
if (!details->printed_details) {
|
|
PR("\nTCP Ref Recv_win Send_win Pending "
|
|
"Unacked Flags Queue\n");
|
|
details->printed_details = true;
|
|
}
|
|
|
|
PR("%p %ld %u\t %u\t %zd\t %d\t %d/%d/%d %s\n", conn,
|
|
atomic_get(&conn->ref_count), conn->recv_win, conn->send_win,
|
|
conn->send_data_total, conn->unacked_len,
|
|
conn->data_mode == TCP_DATA_MODE_RESEND ? 1 : 0, conn->in_connect,
|
|
conn->in_close, sys_slist_is_empty(&conn->send_queue) ? "empty" : "data");
|
|
|
|
details->count++;
|
|
}
|
|
|
|
if (sys_slist_is_empty(&conn->send_queue)) {
|
|
return;
|
|
}
|
|
|
|
if (!details->printed_send_queue_header) {
|
|
PR("\nTCP packets waiting ACK:\n");
|
|
PR("TCP net_pkt[ref/totlen]->net_buf[ref/len]..."
|
|
"\n");
|
|
}
|
|
|
|
PR("%p ", conn);
|
|
|
|
node = sys_slist_peek_head(&conn->send_queue);
|
|
if (node) {
|
|
pkt = CONTAINER_OF(node, struct net_pkt, next);
|
|
if (pkt) {
|
|
struct net_buf *frag = pkt->frags;
|
|
|
|
if (!details->printed_send_queue_header) {
|
|
PR("%p[%ld/%zd]", pkt,
|
|
atomic_get(&pkt->atomic_ref),
|
|
net_pkt_get_len(pkt));
|
|
details->printed_send_queue_header = true;
|
|
} else {
|
|
PR(" %p[%ld/%zd]",
|
|
pkt, atomic_get(&pkt->atomic_ref),
|
|
net_pkt_get_len(pkt));
|
|
}
|
|
|
|
if (frag) {
|
|
PR("->");
|
|
}
|
|
|
|
while (frag) {
|
|
PR("%p[%d/%d]", frag, frag->ref, frag->len);
|
|
|
|
frag = frag->frags;
|
|
if (frag) {
|
|
PR("->");
|
|
}
|
|
}
|
|
|
|
PR("\n");
|
|
}
|
|
}
|
|
|
|
details->printed_send_queue_header = true;
|
|
}
|
|
#endif /* CONFIG_NET_TCP_LOG_LEVEL >= LOG_LEVEL_DBG */
|
|
#endif /* TCP */
|
|
|
|
static int cmd_net_conn(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
ARG_UNUSED(argc);
|
|
ARG_UNUSED(argv);
|
|
|
|
#if defined(CONFIG_NET_OFFLOAD) || defined(CONFIG_NET_NATIVE)
|
|
struct net_shell_user_data user_data;
|
|
int count = 0;
|
|
|
|
PR(" Context \tIface Flags Local Remote\n");
|
|
|
|
user_data.sh = sh;
|
|
user_data.user_data = &count;
|
|
|
|
net_context_foreach(context_cb, &user_data);
|
|
|
|
if (count == 0) {
|
|
PR("No connections\n");
|
|
}
|
|
|
|
PR("\n Handler Callback Proto Local Remote\n");
|
|
|
|
count = 0;
|
|
|
|
net_conn_foreach(conn_handler_cb, &user_data);
|
|
|
|
if (count == 0) {
|
|
PR("No connection handlers found.\n");
|
|
}
|
|
|
|
#if defined(CONFIG_NET_TCP)
|
|
PR("\nTCP Context Src port Dst port "
|
|
"Send-Seq Send-Ack MSS State\n");
|
|
|
|
count = 0;
|
|
|
|
net_tcp_foreach(tcp_cb, &user_data);
|
|
|
|
if (count == 0) {
|
|
PR("No TCP connections\n");
|
|
} else {
|
|
#if CONFIG_NET_TCP_LOG_LEVEL >= LOG_LEVEL_DBG
|
|
/* Print information about pending packets */
|
|
struct tcp_detail_info details;
|
|
|
|
count = 0;
|
|
|
|
if (IS_ENABLED(CONFIG_NET_TCP)) {
|
|
memset(&details, 0, sizeof(details));
|
|
user_data.user_data = &details;
|
|
}
|
|
|
|
net_tcp_foreach(tcp_sent_list_cb, &user_data);
|
|
|
|
if (IS_ENABLED(CONFIG_NET_TCP)) {
|
|
if (details.count == 0) {
|
|
PR("No active connections.\n");
|
|
}
|
|
}
|
|
#endif /* CONFIG_NET_TCP_LOG_LEVEL >= LOG_LEVEL_DBG */
|
|
}
|
|
|
|
#if CONFIG_NET_TCP_LOG_LEVEL < LOG_LEVEL_DBG
|
|
PR_INFO("Set %s to enable %s support.\n",
|
|
"CONFIG_NET_TCP_LOG_LEVEL_DBG", "TCP debugging");
|
|
#endif /* CONFIG_NET_TCP_LOG_LEVEL < LOG_LEVEL_DBG */
|
|
|
|
#endif
|
|
|
|
#if defined(CONFIG_NET_IPV6_FRAGMENT)
|
|
count = 0;
|
|
|
|
net_ipv6_frag_foreach(ipv6_frag_cb, &user_data);
|
|
|
|
/* Do not print anything if no fragments are pending atm */
|
|
#endif
|
|
|
|
#else
|
|
PR_INFO("Set %s to enable %s support.\n",
|
|
"CONFIG_NET_OFFLOAD or CONFIG_NET_NATIVE",
|
|
"connection information");
|
|
|
|
#endif /* CONFIG_NET_OFFLOAD || CONFIG_NET_NATIVE */
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
SHELL_SUBCMD_ADD((net), conn, NULL, "Print information about network connections.",
|
|
cmd_net_conn, 1, 0);
|