net: Add FIOC_FILEPATH ioctl support for tcp/udp/local sockets

Example of /proc/PID/group/fd, which prints the file path:

FD  OFLAGS  TYPE POS       PATH
0   3       1    0         /dev/console
1   3       1    0         /dev/console
2   3       1    0         /dev/console
3   3       9    0         udp:[0.0.0.0:10197<->114.118.7.163:123, tx 0/16384, rx 0/16384, flg 1]
4   1027    9    0         tcp:[0.0.0.0:23<->0.0.0.0:0, tx 0/16384, rx 0/16384 + ofo 0, st 01, flg 31]
5   67      9    0         local:[md:ap]

Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
This commit is contained in:
Zhe Weng 2023-08-02 15:11:52 +08:00 committed by Xiang Xiao
parent 194d0cdec9
commit 817a43de4d
3 changed files with 138 additions and 1 deletions

View File

@ -882,6 +882,11 @@ static int local_ioctl(FAR struct socket *psock, int cmd, unsigned long arg)
ret = -ENOTCONN;
}
break;
case FIOC_FILEPATH:
snprintf((FAR char *)(uintptr_t)arg, PATH_MAX, "local:[%s]",
conn->lc_path);
ret = OK;
break;
case BIOC_FLUSH:
ret = -EINVAL;
break;

View File

@ -25,6 +25,7 @@
#include <nuttx/config.h>
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include <debug.h>
#include <errno.h>
@ -37,6 +38,71 @@
#include "tcp/tcp.h"
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: tcp_path
*
* Description:
* This function generates tcp status as path.
*
* Parameters:
* conn The TCP connection of interest
* buf The buffer to get the path
* len The length of the buffer
*
****************************************************************************/
static void tcp_path(FAR struct tcp_conn_s *conn, FAR char *buf, size_t len)
{
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
uint8_t domain = conn->domain;
#elif defined(CONFIG_NET_IPv4)
const uint8_t domain = PF_INET;
#else
const uint8_t domain = PF_INET6;
#endif
char remote[INET6_ADDRSTRLEN];
char local[INET6_ADDRSTRLEN];
FAR void *laddr = net_ip_binding_laddr(&conn->u, domain);
FAR void *raddr = net_ip_binding_raddr(&conn->u, domain);
snprintf(buf, len, "tcp:["
"%s:%" PRIu16 "<->%s:%" PRIu16
#if CONFIG_NET_SEND_BUFSIZE > 0
", tx %" PRIu32 "/%" PRId32
#endif
#if CONFIG_NET_RECV_BUFSIZE > 0
", rx %u/%" PRId32
# ifdef CONFIG_NET_TCP_OUT_OF_ORDER
" + ofo %d"
# endif
#endif
", st %02" PRIx8
", flg %" PRIx8
"]",
inet_ntop(domain, laddr, local, sizeof(local)),
ntohs(conn->lport),
inet_ntop(domain, raddr, remote, sizeof(remote)),
ntohs(conn->rport),
#if CONFIG_NET_SEND_BUFSIZE > 0
tcp_wrbuffer_inqueue_size(conn),
conn->snd_bufs,
#endif
#if CONFIG_NET_RECV_BUFSIZE > 0
(conn->readahead) ? conn->readahead->io_pktlen : 0,
conn->rcv_bufs,
# ifdef CONFIG_NET_TCP_OUT_OF_ORDER
tcp_ofoseg_bufsize(conn),
# endif
#endif
conn->tcpstateflags,
conn->sconn.s_flags
);
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -86,6 +152,10 @@ int tcp_ioctl(FAR struct tcp_conn_s *conn, int cmd, unsigned long arg)
*(FAR int *)((uintptr_t)arg) = MIN_TCP_MSS;
#endif
break;
case FIOC_FILEPATH:
tcp_path(conn, (FAR char *)(uintptr_t)arg, PATH_MAX);
ret = OK;
break;
default:
ret = -ENOTTY;
break;

View File

@ -25,6 +25,7 @@
#include <nuttx/config.h>
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include <debug.h>
#include <errno.h>
@ -37,6 +38,63 @@
#include "udp/udp.h"
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: udp_path
*
* Description:
* This function generates udp status as path.
*
* Parameters:
* conn The UDP connection of interest
* buf The buffer to get the path
* len The length of the buffer
*
****************************************************************************/
static void udp_path(FAR struct udp_conn_s *conn, FAR char *buf, size_t len)
{
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
uint8_t domain = conn->domain;
#elif defined(CONFIG_NET_IPv4)
const uint8_t domain = PF_INET;
#else
const uint8_t domain = PF_INET6;
#endif
char remote[INET6_ADDRSTRLEN];
char local[INET6_ADDRSTRLEN];
FAR void *laddr = net_ip_binding_laddr(&conn->u, domain);
FAR void *raddr = net_ip_binding_raddr(&conn->u, domain);
snprintf(buf, len, "udp:["
"%s:%" PRIu16 "<->%s:%" PRIu16
#if CONFIG_NET_SEND_BUFSIZE > 0
", tx %" PRIu32 "/%" PRId32
#endif
#if CONFIG_NET_RECV_BUFSIZE > 0
", rx %u/%" PRId32
#endif
", flg %" PRIx8
"]",
inet_ntop(domain, laddr, local, sizeof(local)),
ntohs(conn->lport),
inet_ntop(domain, raddr, remote, sizeof(remote)),
ntohs(conn->rport),
#if CONFIG_NET_SEND_BUFSIZE > 0
udp_wrbuffer_inqueue_size(conn),
conn->sndbufs,
#endif
#if CONFIG_NET_RECV_BUFSIZE > 0
(conn->readahead) ? conn->readahead->io_pktlen : 0,
conn->rcvbufs,
#endif
conn->sconn.s_flags
);
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -48,7 +106,7 @@
* This function performs udp specific ioctl() operations.
*
* Parameters:
* conn The TCP connection of interest
* conn The UDP connection of interest
* cmd The ioctl command
* arg The argument of the ioctl cmd
*
@ -89,6 +147,10 @@ int udp_ioctl(FAR struct udp_conn_s *conn, int cmd, unsigned long arg)
*(FAR int *)((uintptr_t)arg) = MIN_UDP_MSS;
#endif
break;
case FIOC_FILEPATH:
udp_path(conn, (FAR char *)(uintptr_t)arg, PATH_MAX);
ret = OK;
break;
default:
ret = -ENOTTY;
break;