diff --git a/subsys/net/ip/connection.c b/subsys/net/ip/connection.c index b6a41e32631..57f3307aff7 100644 --- a/subsys/net/ip/connection.c +++ b/subsys/net/ip/connection.c @@ -771,6 +771,19 @@ drop: return NET_DROP; } +void net_conn_foreach(net_conn_foreach_cb_t cb, void *user_data) +{ + int i; + + for (i = 0; i < CONFIG_NET_MAX_CONN; i++) { + if (!(conns[i].flags & NET_CONN_IN_USE)) { + continue; + } + + cb(&conns[i], user_data); + } +} + void net_conn_init(void) { #if defined(CONFIG_NET_CONN_CACHE) diff --git a/subsys/net/ip/connection.h b/subsys/net/ip/connection.h index 75072498cc6..4675b62f574 100644 --- a/subsys/net/ip/connection.h +++ b/subsys/net/ip/connection.h @@ -143,6 +143,25 @@ static inline enum net_verdict net_conn_input(enum net_ip_protocol proto, } #endif /* CONFIG_NET_UDP || CONFIG_NET_TCP */ +/** + * @typedef net_conn_foreach_cb_t + * @brief Callback used while iterating over network connection + * handlers. + * + * @param conn A valid pointer on current network connection handler. + * @param user_data A valid pointer on some user data or NULL + */ +typedef void (*net_conn_foreach_cb_t)(struct net_conn *conn, void *user_data); + +/** + * @brief Go through all the network connection handlers and call callback + * for each network connection handler. + * + * @param cb User supplied callback function to call. + * @param user_data User specified data. + */ +void net_conn_foreach(net_conn_foreach_cb_t cb, void *user_data); + void net_conn_init(void); #ifdef __cplusplus diff --git a/subsys/net/ip/net_shell.c b/subsys/net/ip/net_shell.c index 925813e95b9..ffc6a90ce7f 100644 --- a/subsys/net/ip/net_shell.c +++ b/subsys/net/ip/net_shell.c @@ -470,6 +470,61 @@ static void context_cb(struct net_context *context, void *user_data) (*count)++; } +#if defined(CONFIG_NET_DEBUG_CONN) +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 + + int *count = user_data; + /* +7 for []:port */ + char addr_local[ADDR_LEN + 7]; + char addr_remote[ADDR_LEN + 7] = ""; + +#if defined(CONFIG_NET_IPV6) + if (conn->local_addr.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 +#endif +#if defined(CONFIG_NET_IPV4) + if (conn->local_addr.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 +#endif + if (conn->local_addr.family == AF_UNSPEC) { + snprintk(addr_local, sizeof(addr_local), "AF_UNSPEC"); + } else { + snprintk(addr_local, sizeof(addr_local), "AF_UNK(%d)", + conn->local_addr.family); + } + + printk("[%2d] %p %p\t%s\t%16s\t%16s\n", + (*count) + 1, conn, conn->cb, net_proto2str(conn->proto), + addr_local, addr_remote); + + (*count)++; +} +#endif /* CONFIG_NET_DEBUG_CONN */ + #if defined(CONFIG_NET_TCP) static void tcp_cb(struct net_tcp *tcp, void *user_data) { @@ -596,6 +651,19 @@ static int shell_cmd_conn(int argc, char *argv[]) printk("No connections\n"); } +#if defined(CONFIG_NET_DEBUG_CONN) + printk("\n Handler Callback \tProto\t" + "Local \tRemote\n"); + + count = 0; + + net_conn_foreach(conn_handler_cb, &count); + + if (count == 0) { + printk("No connection handlers found.\n"); + } +#endif + #if defined(CONFIG_NET_TCP) printk("\nTCP Src port Dst port Send-Seq Send-Ack MSS " "State\n");